使用SemanticComparison比较嵌套对象属性
-
21-12-2019 - |
题
我正在创建一个需要比较同一类型成员的两个对象的单元测试。我决定使用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"
}
};
}
}
.
这不起作用,因为内部对象通过引用进行比较,而不是成员:
[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);
}
.
要使它工作我必须创建嵌套对象的代理,以便它覆盖默认等式实现。
[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);
}
.
嗯,它可以正常工作,但想象在某些服务代码重构后,我们介绍了导致内部类的值属性与预期值不同的错误。 SemanticComparison的COOL特征是它可以记录导致不等式的成员的名称。但是,在这种情况下,它只会将“内心”返回为不匹配,而不是内部类中特定属性的名称。
我错过了什么?是否可以配置它能够返回实际的不匹配成员。
这显然不是简单数据结构的问题,如在此示例中,但它可能是测试实际寿命代码的不便。
解决方案
因为没有人回答,我会提供自己的答案。
所以,似乎你不能做到它,除非你写一些额外的代码。 我在扩展方法集中包裹了代码。这些方法允许您指定使用内心形象的内部属性/收集属性,而不是通过引用来进行比较。您无需手动创建任何代理,所有这些扩展都在内部处理。并记录所有内部比较的结果,因此您可以确切地查看成员具有无效值。
以下是使用“inhannerlikeness”扩展方法的问题的测试。
[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上找到源代码和更多示例。
不隶属于 StackOverflow