我有一个项目,我在其中接收对象作为DTO,我正在将它们转换为View-Models。为了进行这种转换,我决定制作自定义转换器,进行一些计算,以便从DTO属性转换为View-Models。在所有这些准备好之后,转换工作正常,我想在转换中添加一些单元测试以使其更稳定(我知道这不尊重TDD,但这是我设法做到的)。 / p>
当我想要测试来验证两个View-Models
的相等性时,问题出现了Assert.AreEqual(expected, actual);
因为没有View-Models定义Equals
方法,所以它们永远不会等于引用。我想到了一些方法,并发现可以比较这些对象:
定义Equals
方法。但我不知道定义它是否是一个好习惯,仅用于测试目的。如果我定义它,建议也定义GetHashCode
方法,所以我觉得这个解决方案不是最好的。
我认为另一种可能性是在测试项目中实现IEqualityComparer<T>
,将比较逻辑与主转换项目隔离开来,甚至将其提取到第3个项目中,以便转换模块可以使用它将来如果有必要的话。这个实现看起来不错,但我不知道是否值得添加另一个包含许多类的项目,这些项目也应该进行测试。
我在Stack Overflow question上找到的第三种方法,看起来很有趣,是序列化两个对象并比较字符串。问题是我不知道这是一个很好的编程实践。
哪些是比较对象的最佳方式?我错过了一些可能更有效的方法吗?
注意:View-Models是复杂的对象,我无法改变转换为其他技术的方式。
答案 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)。
基于序列化的方法过于脆弱,因为它依赖于不相关的功能(即序列化)来测试您实际测试的功能(即转换)。