C # ValidationResult Утверждение равенства значения сбой с Assert.AreEqual

1

У меня простая реализация ValidationRule:

public class IntegerRangeRule : ValidationRule
{
    public Int32 Max { get; set; }
    public Int32 Min { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        int integer;

        if(string.IsNullOrEmpty((string)value))
        {
            return new ValidationResult(false, "Field cannot be empty");
        }

        if (Int32.TryParse((string) value, out integer))
        {
            if((integer < Min) || (integer > Max))
                return new ValidationResult(false, string.Format("Enter a value between {0} and {1}.", Min, Max));
        }
        else
        {
            return new ValidationResult(false, "Illegal characters: " + (string)value);
        }

        return ValidationResult.ValidResult;
    }
}

Я написал следующий unit тест для метода Validation:

[TestMethod()]
public void ValidateTest_InputTooSmall()
{
    //Setup
    var target = new IntegerRangeRule()
    {
        Max = 100,
        Min = 1
    };
    var expected = new ValidationResult(false, "Enter a value between 1 and 100.");

    //Exercise
    var actual = target.Validate("0", null);

    //Verify
    Assert.AreEqual(expected.ErrorContent, actual.ErrorContent);
    Assert.AreEqual(expected.IsValid, actual.IsValid);
    Assert.AreEqual(expected.GetHashCode(), actual.GetHashCode());
    Assert.AreEqual(expected, actual);
}

Вот улов.

Первые три утверждения все проходят. Но последний не удался.

Если я заменю

...
    if (Int32.TryParse((string) value, out integer))
    {
        if((integer < Min) || (integer > Max))
            return new ValidationResult(false, string.Format("Enter a value between {0} and {1}.", Min, Max));
    }
...

с постоянной строкой.

...
    if (Int32.TryParse((string) value, out integer))
    {
        if((integer < Min) || (integer > Max))
            return new ValidationResult(false, "Enter a value between 1 and 100.");
    }
...

Последнее утверждение пройдет.

Я не понимаю, что вызывает здесь проблему. Спасибо.

Теги:
unit-testing

1 ответ

2
Лучший ответ

ValidationResult содержит это в Equals:

return (IsValid == vr.IsValid) && (ErrorContent == vr.ErrorContent);

Поскольку ErrorContent является объектом, это сравнение ссылок, а не сравнение значений. В вашем случае вы создаете новую строку с использованием String.Format и сравниваете эту ссылку с литералом, поэтому результат всегда является ложным. Когда вы меняете его на одну и ту же буквенную строку, она проходит, потому что литералы интернированы CLR.

Тем временем ваша тестовая структура, вероятно, вызывает Object.Equals(object, object) внутри своего метода Assert.AreEqual, который вызывает String переопределенный метод Equals. Это сравнивает значение.

  • 0
    Спасибо за ответ, кстати. Эм ... Конечно, было бы полезно, если бы у меня был доступ к исходному коду. Так как ErrorContent является объектом, а равенство ссылок проверяется. Как получилось первое утверждение Assert.AreEqual (Ожидается. Ошибка. Факт. Факт. Ошибка.); не подвела?
  • 0
    @FrankLiu У вас есть доступ к исходному коду фреймворка по адресу referenceource.microsoft.com.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню