A reader asked me how AutoFixture can deal with arrays as fields on a class. More specifically, given a class like MyClassA, how can AutoFixture assign a proper array with initialized values to Items?

public class MyClassA
{
    public MyClassB[] Items;
    public MyClassC C;
    public MyClassD D;
}

Ignoring the bad practice of publicly exposing fields, the main problem is that AutoFixture has no inherent understanding of arrays, so if we try to create a new instance of MyClassA by invoking the CreateAnonymous method, we would end up with Items being an array of nulls.

Obviously we want a populated array instead. There are at least a couple of ways to reach this goal.

The simplest is just to create it and modify it afterwards:

var mc = fixture.CreateAnonymous<MyClassA>();
mc.Items = fixture.CreateMany<MyClassB>().ToArray();

Although the CreateAnomymous method will assign an unitialized array, we immediately overwrite the value with an initialized array. The CreateMany method returns an IEnumerable<MyClassB> on which we can use the ToArray extension method to create an array.

The next option is to do almost the same thing, but as a single operation:

var mc = fixture.Build<MyClassA>()
    .With(x => x.Items, 
        fixture.CreateMany<MyClassB>().ToArray())
    .CreateAnonymous();

Besides the different syntax and the lower semicolon count, the biggest difference is that in this case the Items field is never assigned an unitialized array because the With method ensures that the specified value is assigned immediately.

If you get tired of writing this Builder sequence every time you want to create a new MyClassA instance, you can Customize the Fixture:

fixture.Customize<MyClassA>(ob =>
    ob.With(x => x.Items, 
        fixture.CreateMany<MyClassB>().ToArray()));

With this customization, every time we invoke

var mc = fixture.CreateAnonymous<MyClassA>();

we will get an instance of MyClassA with a properly initialized Items array.

I hope you find one or more of these methods useful.


Comments

Murali
Thanks Mark for your very quick answer to my question.

Murali
2009-12-07 14:33 UTC


Wish to comment?

You can add a comment to this post by sending me a pull request. Alternatively, you can discuss this post on Twitter or Google Plus, or somewhere else with a permalink. Ping me with the link, and I may add it as a comment.

Published

Saturday, 05 December 2009 00:41:45 UTC

Tags



"Our team wholeheartedly endorses Mark. His expert service provides tremendous value."
Hire me!