У меня простая реализация 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.");
}
...
Последнее утверждение пройдет.
Я не понимаю, что вызывает здесь проблему. Спасибо.
ValidationResult содержит это в Equals:
return (IsValid == vr.IsValid) && (ErrorContent == vr.ErrorContent);
Поскольку ErrorContent
является объектом, это сравнение ссылок, а не сравнение значений. В вашем случае вы создаете новую строку с использованием String.Format
и сравниваете эту ссылку с литералом, поэтому результат всегда является ложным. Когда вы меняете его на одну и ту же буквенную строку, она проходит, потому что литералы интернированы CLR.
Тем временем ваша тестовая структура, вероятно, вызывает Object.Equals(object, object)
внутри своего метода Assert.AreEqual
, который вызывает String переопределенный метод Equals. Это сравнивает значение.