Coordinator
Aug 3 2010 at 8:48 PM
Edited Aug 3 2010 at 8:51 PM
|
Thanks for writing and thank you for using AutoFixture.
Quite surprisingly you've actually discovered a behavior I was not aware of. Is it by design? No, not really. Is it a bug? Perhaps, but I'm not quite sure about that either...
As AutoFixture behaves right now (and has always done), it automatically fills all writable properties of instances it creates itself. In this case, when you ask it to create a ComplexParent, it populates the writable properties before serving the instance.
In other words, Bla and Blub are populated because they are writable.
However, the ComplexChild property is read-only, so AutoFixture never creates an instance of it - and since it doesn't create an instance, its properties are never populated.
Now, I realize that ComplexChild in itself has writable properties, so it's not unreasonable to expect its properties to be populated. However, that's not what AutoFixture currently does because the population ignores read-only properties, even when they
are complex and have writable properties of their own.
You could certainly argue that this is not intuitive. I'm not going to argue back :)
However, one thing is intuition, another is what an API implies. In most cases, a read-only property strongly signals that the parent controls the property. This could be a signal to AutoFixture that it should keep off that property.
The reason I've never before discovered this behavior despite having used AutoFixture heavily for more than a year is that I rarely design my classes like that. While I often have complex read-only properties, they tend to be populated with appropriate data.
Even if the complex type has writable properties, I make sure that they are always in a valid state. So even when AutoFixture haven't been filling properties like those, I've never discovered it because there would have been values none the less.
Now, a completely different situation arises if we change the ComplexChild property to be writable. In that case, AutoFixture will assign a new value to the property, and since it creates an instance of ComplexChild to do that, it also assigns auto-properties
to it. That's one possible workaround.
Another possible workaround is to explicitly fill the properties afterwords, but this can quickly get clunky:
var result = fixture.Build<ComplexParent>()
.Do(x => x.Child.Bar = fixture.CreateAnonymous<int>())
.Do(x => x.Child.Foo = fixture.CreateAnonymous("Foo"))
.CreateAnonymous();
I'm creating an issue from this question. While I don't think it's a good idea to change the current auto-property behavior (it would be a breaking change), it might be a good idea to add recursive auto-properties as an option. However, in any case I'll
be postponing this past the AutoFixture 2.0, release as it's not entirely trivial to add this feature.
Please let me know if you have further questions on this or other issues.
|