3

I want to create a customization to restrict the values of an enum supplied by AutoFixture. The only examples I've been able to find so far use the imperative style (such as this).

Given the following enum definition:

public enum AnEnum
{
    A,
    B,
    C
}

I would like to restrict the values to AnEnum.B and AnEnum.C. I've tried some variations of the following code.

public class EnumCustomization : ICustomization
{
    public virtual void Customize(IFixture fixture)
    {
        fixture.Customize<AnEnum>(
            c => c.FromFactory(() => new Generator<AnEnum>(fixture).First(e => e != AnEnum.A)));
    }
}

However, they all inevitably lead to an AutoFixture.ObjectCreationExceptionWithPath exception. Without the customization AutoFixture will create a value of AnEnum as normal. Therefore, I think the problem lies with my attempts at customization rather than any circular references elsewhere.

biff
  • 41
  • 5

1 Answers1

2

OOTB, AutoFixture uses round-robin strategy to generate enum values. If you call fixture.Create<AnEnum>() multiple times, you receive a sequence of values such as A, B, C, A, B ... etc.

There is a customization that uses default EnumGenerator and just ignores C values. It might look suboptimal, but it does the trick:

public class AnEnumEnumGenerator : ISpecimenBuilder
{
    private readonly EnumGenerator _builder = new EnumGenerator();

    public object Create(object request, ISpecimenContext context)
    {
        var value = _builder.Create(request, context);
        if (value is AnEnum @enum && @enum == AnEnum.C)
        {
            return _builder.Create(request, context);
        }

        return value;
    }
}

Now apply the customization and check the result:

fixture.Customize<AnEnum>(c => new AnEnumEnumGenerator());

Console.Out.WriteLine("result = {0}", fixture.Create<AnEnum>());
Console.Out.WriteLine("result = {0}", fixture.Create<AnEnum>());
Console.Out.WriteLine("result = {0}", fixture.Create<AnEnum>());
Console.Out.WriteLine("result = {0}", fixture.Create<AnEnum>());

Output:

result = A
result = B
result = A
result = B
Serhii Shushliapin
  • 2,528
  • 2
  • 15
  • 32