Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working with AutoFixture #15

Open
peheje opened this issue May 5, 2021 · 1 comment
Open

Working with AutoFixture #15

peheje opened this issue May 5, 2021 · 1 comment

Comments

@peheje
Copy link

peheje commented May 5, 2021

Has anyone gotten this package to work with AutoFixture to automatically create your test data?

Maybe with some type of generic AutoFixture specimen builder?

I believe AutoFixture would like the properties to be public set or for the object to have a public ctor.

@Ergamon
Copy link

Ergamon commented Jul 19, 2021

I looked at the library today for evaluation.

The way AutoFixture works, it does not play nice with it. AutoFixture just sees a class with an empty constructor.

So indeed you need some kind of customization to tell AutoFixture to use the From method.

With a few minutes of coding I came up with this:

  public class ValueOfSpecimenBuilder : ISpecimenBuilder
  {
    private const string FactoryMethodName = "From";

    object ISpecimenBuilder.Create(object request, ISpecimenContext context)
    {
      var type = request as Type;

      var valueType = GetValueType(type);

      if(valueType is null)
      {
        return new NoSpecimen();
      }

      var value = context.Resolve(valueType);

      return Create(type, value);
    }

    private static object Create(Type type, object value)
    {
      var method = type.GetMethod(
        FactoryMethodName,
        BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);

      var parameters = new object[]
      {
        value,
      };

      return method.Invoke(null, parameters);
    }

    private static Type GetValueType(Type type)
    {
      while (type != null)
      {
        if (type.IsGenericType)
        {
          var definition = type.GetGenericTypeDefinition();

          if (definition == typeof(ValueOf<,>))
          {
            var arguments = type.GetGenericArguments();
            return arguments[0];
          }
        }
        
        type = type.BaseType;
      }
      
      return null;
    }
  }

Probably some room for improvement, but it works.

  public class Gtin : ValueOf<string, Gtin>
  { 
  }

  var fixture = new Fixture();
  fixture.Customizations.Add(new ValueOfSpecimenBuilder());

  var gtin = fixture.Create<Gtin>();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants