C#ValidationResult值相等断言失败,出现Assert.AreEqual

时间:2014-08-22 06:52:07

标签: c# unit-testing

我有一个简单的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;
    }
}

我为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.");
    }
...

最后一个断言将通过。

我不明白这里导致问题的原因。谢谢。

1 个答案:

答案 0 :(得分:2)

ValidationResult在Equals中包含此内容:

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

由于ErrorContent是一个对象,因此这是一个参考比较,而不是值比较。在您的情况下,您使用String.Format生成一个新字符串,并将该引用与文字进行比较,因此结果始终为false。当您将其更改为它传递的相同文字字符串时,因为文字由CLR实现。

同时,您的测试框架可能在其Object.Equals(object, object)方法中调用Assert.AreEqual,该方法调用String的重写方法。这进行了价值比较。