I'm not sure if this is possible but i thought it was worth asking.
We have a number of objects that have a hierarchy of other sub objects. Instead of using a series of IEnumerable collections we use dictionaries so that when the data is queried in MongoDb it's easy/fast to traverse the hierarchy. For example:
In the main model we have something like:
public Dictionary<string, TopLevelGroup> TopGroups { get; set; }
Then in TopLevelGroup we have something like:
public Dictionary<string, SecondLevelGroup> SecondLevelGroups { get; set; }
The key has to be a string so that it can be stored in Mongo as a ReferencedDictionary (I think that's right) and the data can be accessed simply by doing:
TopLevelGroup[keyA].SecondLevelGroup[keyB].Property
All of the keys are the id property of the object (there is a generic IDocument interface for them too which requires all documents have an Id...of course).
So what I want to do in AutoFixture is make it so all auto-generated dictionaries use the object's Id as the key (and not a randomly generated string).
I suspect this is a bit crazy and unsupported but I wanted to ask just incase as I don't know AutoFixture too well at the moment.
No, it's not at all crazy, and it is supported.
That scenario is what the Customize method is useful for.
With that method you customize how the object is created.
You could maybe do this:
fixture.Customize<TopLevelGroup>(
c => c.With(
propertyPicker: x => x.SecondLevelGroups,
valueFactory: (IEnumerable<SecondLevelGroup> input) => input.ToDictionary(y => y.Id)));
fixture.Customize<MainModel>(
c => c.With(
propertyPicker: x => x.TopGroups,
valueFactory: (IEnumerable<TopLevelGroup> input) => input.ToDictionary(y => y.Id)));
The With
method is used to specify a value for a property. The first argument is the propertypicker, e.g. x => x.SecondLevelGroups
The second argument is either a value, or a valuefactory. The valuefactory can take an input, which autofixture will populate. For example an IEnumerable<SecondLevelGroup>
which we then can convert to a dictionary with the key that we want.