我想知道是否有办法比较MBUnit中的两个对象,以便在对象“看起来”相同时传递测试,即使这些是不同的实例?
例如:
[TestFixture]
class ComparisonTestFixture
{
class foo
{
public string bar;
}
[Test]
public void ComparisonTest()
{
foo foo1 = new foo()
{
bar = "baz"
};
foo foo2 = new foo()
{
bar = "baz"
};
//This assertion should be successful, but it isn't
//*** Failures ***
//Expected values to be equal.
//Expected Value & Actual Value : {foo: bar = "zzz...."}
//Remark : Both values look the same when formatted but they are distinct instances.
Assert.AreEqual(foo1,foo2);
}
}
Assert.AreEqual()不适用于此(测试失败,请参阅上面的源代码)。因为它标注“两个值在格式化时看起来相同但它们是不同的实例”,我认为必须有一些方法来构建MbUnit已经没有在我自己的代码中将对象序列化为XML。
我是否必须为此编写自己的Assert扩展方法?
答案 0 :(得分:7)
Yann还实现了一个StructuralEqualityComparer,它给出了每个属性的一组lambdas,逐个比较属性值。值得一看。
此处有更多信息:http://www.gallio.org/api/html/T_MbUnit_Framework_StructuralEqualityComparer_1.htm
答案 1 :(得分:4)
有一个overload of Assert.AreEqual()
以IEqualityComparer<T>
作为参数,另一个采用EqualityComparison<T>
否则您可以使用Assert.AreEqual(Assert.XmlSerialize(a), Assert.XmlSerialize(b))
答案 2 :(得分:1)
我建议您覆盖类上的Equals
方法以执行所需的比较。这允许您定义值相等而不是引用相等。需要注意的是,如果覆盖GetHashCode
以确保两个相等的对象也返回相同的哈希码,则还必须覆盖Equals
。这是一个非常简单的例子;
public class Foo {
public String Bar {
get;
set;
}
public String Baz {
get;
set;
}
public override Boolean Equals(Object other) {
Foo otherFoo = other as Foo;
return otherFoo != null
&& Bar.Equals(otherFoo.Bar)
&& Baz.Equals(otherFoo.Baz);
}
public override Int32 GetHashCode() {
return Bar.GetHashCode() ^ Baz.GetHasCode();
}
}
如果您不想覆盖Equals
并且您真的只想按属性比较实例属性,则可以使用反射:
public static Boolean AreEqual<T>(T a, T b) {
foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
if (!Object.Equals(propertyInfo.GetValue(a, null),
propertyInfo.GetValue(b, null)))
return false;
return true;
}
答案 3 :(得分:1)
我通常做的只是实现ToString()覆盖 - 这被认为是最好的做法。
所以在你的情况下:
public override string ToString()
{
return string.Format("Class foo, bar={0}",bar);
}
然后你的AreEqual(foo1,foo2)
将实际报告正确的结果,因为它只会调用默认的ToString实现