​Problem

When writing unit tests test objects have to be created for checking flow of the application, filtering of the data and the mapping of the test data to the outputted objects. This can be time consuming and when this test data is shared between many different tests and services the actually tests become difficult to understand, difficult to update due to the tight coupling of this data and none atomic.

Solution

The EntityGenerator class creates a fully populated object including child and grand child objects (depths of which is configurable - default is set to 3 levels) as well as lists of objects. This means that properties that are required to test mapping are automatically set and the only required updates are to the properties that either determine execution flow or those used in the filtering. This then unsures that tests can be fully atomic as no test objects are shared among different tests (Caveat - This should be the goal but in the real world occasionally test data will need to be shared but this should be only done to aid readability).

How it works

Entity generator uses refelction to to create and set all the relevent properties.

​Getting started

The easiest way to use the class is to use its static generic created method as seen in the example below:

var customer = EntityGenerator.Create<Customer>();

To change property values for filtering or execution flow you have 2 choices:
1. Set t​he property values after object creation like:

var customer = EntityGenerator.Create<Customer>();
customer.name = "John";
customer.Postcode = "BA1 1AA"

2. Use the Action method parameter on the Create method like:

var customer = EntityGenerator.Create<Customer>(
p => p.Name = "John";
p => p.Postcode = "BA1 1AA");

The second method has 2 benefits (IMHO):
1. Readability - It's easier to see what you are setting up - It's all done in one 'atomic' step.
2. As it's a single method operation you can step over it in when debuging in a single key press.

More examples:

var plan = EntityGenerator.Create<AggregatePlan>(
p => p.RateTypeMaturityDate = DateTime.Today.AddDays(numberOfDaysPriorToAction),
p => p.PlanStatus = PlanEnumerations.PlanStatus.InForce,
p => p.InterestType = InterestRateEnumerations.Type.Fixed);

var holdingPlan = EntityGenerator.Create<AggregatePlan>(
p => p.PlanWrapperNumber = plan.PlanWrapperNumber,
p => p.ProductComponentType = ProductEnumerations.ProductComponentType.Holding,
p => p.InterestRate = 123.45m,
p => p.RateEffectiveFrom = DateTime.MinValue,
p => p.RateEffectiveTo = null);

var onlinePartner = EntityGenerator.Create<OnlinePartner>(
p => p.ProductWrapperId = plan.ProductWrapperCode,
p => p.ShortCode = "AA");

var customers = EntityGenerator.Create<IEnumerable<Customer>>();

Rules which EntityGenerator follows

The class you want generating must have a default constructor even if it a private default constructor.
Properties which are strings are set to the acual property name.
Any numeric values start at 1 and then following numeric values incremented. i.e. if an object has 3 integer properties then the first is set to 1, the second to 2 etc. etc.
Any Properties that are not found in the CLR (basically self created classes) entities will be automatically generated upto a depth of 3 levels, This can be increated / decreased by setting the max depth parameter on the Create method.
Any enumerable properties with be generated with a single item in the list.
Dictionaries will not be generated and will generate an exception. However the default behaviour of the entity generator will be to swallow this exception. This can be overriden by setting the EntityGeneratorOptions​ flags on the Create method.
Properties with private setters will not be set. This is the default implementation although this can be overriden by setting the EntityGeneratorOptions flags on the Create method.
Nullable objects will always be set
DateTime values will be set to the current date.
The default value for any properties that cannot be set, or throw an exception, will be null.

Last edited Jul 27, 2015 at 3:37 PM by KelbobK5, version 1