改变对象以在测试中验证深度克隆

Mutating an object to validate a deep clone in tests

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

方法

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

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

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

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

ef:字符串为空,整数为 0,等等

此外,用户可能会做类似的事情:

public int MyNumber = 5;

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

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

我也有像 TimeSpans 这样的东西。

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

根据反思和 random-values:

实现目标的一些 high-level 想法
  1. 为给定类型创建 1 个对象
  2. 循环对象的所有成员(属性和字段)Reflection Api。递归处理 reference-typed 个子成员
  3. 对于对象图中的每个 value-typed 成员,使用您的 random-function 设置它的值(为每种可能的值类型单独生成 random-value)。
  4. 执行 DoDeepClone 以创建克隆对象
  5. 对原始对象和克隆对象执行 DeepEqual 并声明它们的相等性

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