我正在创建单元测试,需要成员比较两个相同类型的对象。我决定使用SemanticComparison库来处理此任务,而无需编写自定义比较器代码。它在比较平面对象时效果很好,当对象包含也需要成员比较的嵌套对象时会出现问题。
public class Outer
{
public string Name { get; set; }
public Inner Inner { get; set; }
}
public class Inner
{
public string Name { get; set; }
public string Value { get; set; }
}
public class Service
{
public Outer Method()
{
return new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value1"
}
};
}
}
这不起作用,因为Inner对象是通过引用进行比较,而非成员进行比较:
[Test]
public void SimpleTest1()
{
// setup
var expectedLikeness = new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value1"
}
}.AsSource().OfLikeness<Outer>();
var sut = new Service();
// exercise sut
var actual = sut.Method();
// verify
expectedLikeness.ShouldEqual(actual);
}
为了使它工作,我必须创建嵌套对象的代理,以便它覆盖默认的equals实现。
[Test]
public void SimpleTest2()
{
// setup
var expectedLikeness = new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value1"
}.AsSource().OfLikeness<Inner>().CreateProxy()
}.AsSource().OfLikeness<Outer>();
var sut = new Service();
// exercise sut
var actual = sut.Method();
// verify
expectedLikeness.ShouldEqual(actual);
}
嗯,它运行正常,但想象一下,在一些服务代码重构后,我们引入了导致Inner类的value属性与预期值不同的bug。 SemanticComparison的一个很酷的特性是它可以记录导致不平等的成员的名称。但是,在这种情况下,它只会返回“Inner”作为不匹配,而不是Inner类中特定属性的名称。
我错过了什么吗?是否可以将其配置为能够返回实际的不匹配成员。
对于简单的数据结构来说,这显然不是一个问题,就像在这个例子中一样,但它可能会给测试现实代码带来不便。
答案 0 :(得分:3)
由于没有人回答,我会提供自己的答案。
所以,看起来你不能这样做OOTB,除非你写一些额外的代码。 我已将代码包装在一组扩展方法中。这些方法允许您指定应使用内部相似性而不是引用来比较内部属性/集合属性。您无需手动创建任何代理,所有内容都由这些扩展内部处理。并记录所有内部比较的结果,因此您可以确切地看到哪个成员具有无效值。
以下是使用“WithInnerLikeness”扩展方法的问题的测试。
[Test]
public void ServiceTest3()
{
// setup
var expected = new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value2"
}
};
var expectedLikeness = expected.AsSource().OfLikeness<Outer>()
.WithInnerLikeness(d => d.Inner, s => s.Inner)
;
var sut = new Service();
// exercise sut
var actual = sut.Method();
// verify
expectedLikeness.ShouldEqual(actual);
}
您可以看到内部对象的值属性不匹配,因此测试应该失败。它在输出中失败并显示以下消息:
Comparing inner properties using likeness. Source: s => s.Inner Destination: d => d.Inner.
The source and destination values are not equal. Details: The provided value ClassLibrary1.Inner did not match the expected value ClassLibrary1.Inner. The following members did not match:
- Value.
Ploeh.SemanticComparison.LikenessException : The provided value ClassLibrary1.Outer did not match the expected value ClassLibrary1.Outer. The following members did not match:
- Inner.
您可以在github上找到源代码和更多示例。
答案 1 :(得分:0)
这真是可惜,不开箱即用。
您也可以尝试here,请参见Fluent Assertions。
actual.Should().BeEquivalentTo(expected);
在比较,成员排除等方面有很多灵活性,并且开箱即用地支持嵌套对象属性。
希望这会有所帮助!