jmasterx
jmasterx

Reputation: 54133

Mutating an object to validate a deep clone in tests

I have an interface called IDeepClonable which exposes the method DoDeepClone.

however for performance reasons, every deep clone is implemented by hand.

I want to write a test that will be able to check on any object that implements the interface in my assembly, that it does indeed deep clone correctly.

Validating that is easy, I have a library called DeepEqual to check this.

The problem is to make sure all fields do not have the default value!

ef: null for string, 0 for int, etc.

Moreover, the user might do something like:

public int MyNumber = 5;

Well, I can forget to deep clone it but the test will still b=pass because both original and clone have 5 as value.

What would be a way to mutate any arbitrary object (mostly, value types) to make sure every field is different?

I have things like TimeSpans as well.

The naive solution is to simply build a human maintained list of default values for types but I'm wondering if there is a way to automate this.

Upvotes: 0

Views: 167

Answers (1)

Risto M
Risto M

Reputation: 3009

Some high-level idea to achieve your goal based on reflection and random-values:

  1. Create 1 object for given type
  2. Loop for all members (properties and fields) of object with Reflection Api. Handle reference-typed child members recursively
  3. For every value-typed members in object graph, set it's value with your random-function (separate random-value generation for every possible value type).
  4. Execute DoDeepClone to create cloned object
  5. Execute DeepEqual for original and cloned object and assert their equality

It is crucial that Random-function in phase 3 generates purely random value. In case of i.e bool-type it is possible that generated value is identical to default value (since there are 2 possible values). But you can execute this algorithm multiple times to be sure that unique values are used at least once.

Upvotes: 1

Related Questions