Search code examples
autofixture

Customizing the creation of anonymous sequences in AutoFixture


Using anonymous sequences, I can create sequences of objects when I don't care so much about how many, or what type of sequence it is:

public class Foo { public string Bar { get; set; } }

var fixture = new Fixture();
var foos = fixture.CreateMany<Foo>();

Is there some way I can customize the creation of such sequences, and e.g. set a property on each item in the collection, in a way that considers the entire collection at once, and not just one item at a time?

For example, is there a way to achieve the following?

public interface ISortable
{
    int SortOrder { get; set; }
}

public class Foo : ISortable
{
    public string Bar { get; set; }
    public int SortOrder { get; set; }
}

var fixture = new Fixture();

// TODO: Customize the fixture here

var foos = fixture.CreateMany<Foo>();

// foos now have sort-order set to e.g. a multiple of their index
// in the list, so if three items, they have sort order 0, 10, 20.

Solution

  • It's been a while since I handed over control of AutoFixture, so my information could be out of date, but I don't think there's any feature like that. What I usually do in cases like that is that use normal code to configure what AutoFixture generates. In this particular case, you can use a zip to achieve the desired result; prototype:

    [Fact]
    public void SetSortOrderOnFoos()
    {
        var fixture = new Fixture();
        var foos = fixture
            .CreateMany<Foo>()
            .Zip(
                Enumerable.Range(0, fixture.RepeatCount),
                (f, i) => { f.SortOrder = i * 10; return f; });
    
        Assert.Equal(3, foos.Count());
        Assert.Equal( 0, foos.ElementAt(0).SortOrder);
        Assert.Equal(10, foos.ElementAt(1).SortOrder);
        Assert.Equal(20, foos.ElementAt(2).SortOrder);
    }
    

    This test isn't robust, but I hope it communicates the core idea.