如何在单元测试中测试两个对象的相等性?

时间:2016-07-14 19:42:17

标签: c# unit-testing architecture compare equality

我有一个项目,我在其中接收对象作为DTO,我正在将它们转换为View-Models。为了进行这种转换,我决定制作自定义转换器,进行一些计算,以便从DTO属性转换为View-Models。在所有这些准备好之后,转换工作正常,我想在转换中添加一些单元测试以使其更稳定(我知道这不尊重TDD,但这是我设法做到的)。 / p>

当我想要测试来验证两个View-Models

的相等性时,问题出现了
Assert.AreEqual(expected, actual);

因为没有View-Models定义Equals方法,所以它们永远不会等于引用。我想到了一些方法,并发现可以比较这些对象:

  1. 定义Equals方法。但我不知道定义它是否是一个好习惯,仅用于测试目的。如果我定义它,建议也定义GetHashCode方法,所以我觉得这个解决方案不是最好的。

  2. 我认为另一种可能性是在测试项目中实现IEqualityComparer<T>,将比较逻辑与主转换项目隔离开来,甚至将其提取到第3个项目中,以便转换模块可以使用它将来如果有必要的话。这个实现看起来不错,但我不知道是否值得添加另一个包含许多类的项目,这些项目也应该进行测试。

  3. 我在Stack Overflow question上找到的第三种方法,看起来很有趣,是序列化两个对象并比较字符串。问题是我不知道这是一个很好的编程实践。

  4. 哪些是比较对象的最佳方式?我错过了一些可能更有效的方法吗?

    注意:View-Models是复杂的对象,我无法改变转换为其他技术的方式。

2 个答案:

答案 0 :(得分:3)

我非常喜欢Fluent Assertions的ShouldBeEquivalentTo方法。

actual.ShouldBeEquivalentTo(expected);

默认情况下,此&#34;只是工作&#34;,假设您传入的对象在结构上都是等效的,但您可以提供其他参数来自定义您希望如何进行比较。例如,如果您只想检查对象的几个部分的等价性,您可以说:

actual.ShouldBeEquivalentTo(new {
    expected.Name,
    expected.Description,
    expected.Code
}, options =>
    options.ExcludingMissingMembers);

答案 1 :(得分:3)

你的第二种方法比其他两种方法要好得多,因为它将特定于测试的代码与单元测试结合在一起,同时也因为它可以让你改变你对两个View-Models相同的定义。

将等式比较器移动到一个单独的项目中是不值得的:如果您打算共享相等比较逻辑,那么您也可以将它放入您的对象中。另一方面,如果它仅用于测试,那么你应该将它与测试结合起来(即使用你的方法#1)。

基于序列化的方法过于脆弱,因为它依赖于不相关的功能(即序列化)来测试您实际测试的功能(即转换)。

相关问题