I'm using AutoFixture to generate data for a structure involving a parent object and complex child objects, like this:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public Child[] Children { get; set; }
}
public class Child
{
public string Name { get; set; }
public int ParentId { get; set; }
}
Is there a way to automatically set the property ParentId
of the generated Child
object to the id assigned to the parent? Right now my solution looks like this, which isn't very pretty:
var parent = fixture.Build<Parent>().Without(p => p.Children).CreateAnonymous();
parent.Children = fixture.CreateMany<Child>(10).ToArray();
foreach (var i in parent.Children)
{
i.ParentId = parent.Id;
}
It feels like there's a better way to do this that I am missing? I looked into creating a custom ISpecimenBuilder
but didn't manage to solve it that way either.
AutoFixture is based on a set of rules and assumptions about the API it may be asked to work with. Consider that it's been created and compiled without any prior knowledge of the Child
and Parent
classes, or any other types in a given API. All it has to work with is the public API.
Think of AutoFixture as a very dim programmer who doesn't even understand your language (not even English). The more fool-proof you can make your API, the easier it will be to use AutoFixture with it.
The problem with circular references like the Parent/Child relationship described here is that it breaks encapsulation. You'll need to create at least one of the class instances initially in an invalid state. That it's difficult to make AutoFixture work with such an API should mainly be taken as a warning sign that the API might benefit from refactoring.
Additionally, the .NET Framework Design Guidelines recommends against exposing arrays as properties - particularly writable properties. Thus, with a better encapsulated design, the API might be much easier to work with, both for AutoFixture and yourself and your colleagues.
Given the API above, I don't see any way this can be made much easier to work with. Consider how to remove the circular reference and make collection properties read-only, and it will be much easier.
For the record, I haven't written an API with a circular reference for years, so it's quite possible to avoid those Parent/Child relations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With