【问题标题】:Mutating an object to validate a deep clone in tests变异对象以验证测试中的深层克隆
【发布时间】:2018-02-21 17:50:55
【问题描述】:

我有一个名为IDeepClonable 的接口,它公开了DoDeepClone 方法。

但出于性能原因,每个深度克隆都是手动实现的。

我想编写一个测试,它能够检查在我的程序集中实现接口的任何对象,它确实正确地进行了深度克隆。

验证很容易,我有一个名为 DeepEqual 的库来检查这个。

问题是要确保所有字段都没有默认值!

ef: null 表示字符串,0 表示 int 等

此外,用户可能会执行以下操作:

public int MyNumber = 5;

好吧,我可以忘记深度克隆它,但测试仍然会 b=通过,因为原始和克隆的值都是 5。

有什么方法可以改变任意对象(主要是值类型)以确保每个字段都不同?

我也有类似 TimeSpan 的东西。

天真的解决方案是简单地构建一个人工维护的类型默认值列表,但我想知道是否有办法自动执行此操作。

【问题讨论】:

  • 我知道你来自哪里。但在某种程度上,问题归结为如何在没有“安排”的情况下编写有效的单元测试。为了成功测试,您必须创建测试条件,其中包括非默认值。我通常不在测试中使用随机值,但也许在这种情况下它会有所帮助。随机整数、随机日期、字符串的 guid。

标签: c# unit-testing clone


【解决方案1】:

一些基于反射和随机值实现目标的高级想法:

  1. 为给定类型创建 1 个对象
  2. 循环使用Reflection Api 的对象的所有成员(属性和字段)。递归处理引用类型的子成员
  3. 对于对象图中的每个值类型成员,使用您的随机函数设置它的值(为每种可能的值类型单独生成随机值)。
  4. 执行DoDeepClone创建克隆对象
  5. 对原始对象和克隆对象执行 DeepEqual 并断言它们的相等性

阶段 3 中的 Random-function 生成纯随机值至关重要。在即布尔类型的情况下,生成的值可能与默认值相同(因为有 2 个可能的值)。但是您可以多次执行此算法,以确保至少使用一次唯一值。

【讨论】:

    猜你喜欢
    • 2016-12-20
    • 2010-09-09
    • 1970-01-01
    • 2012-06-05
    • 2013-09-06
    • 2013-10-11
    • 2018-03-21
    相关资源
    最近更新 更多