Question

I'm trying to write a suite of database integration tests for my domain which uses Entity Framework. I would prefer to autofixture objects in some scenarios. My ideal syntax would be something like

[TestMethod]
public void AutofixtureMyEntityEntity()
{
    var fixture = new Fixture();

    fixture.Customize<MyEntity>(
      c => c.FromFactory<MyDbContext>(ctx => ctx.Set<MyEntity>().Create()));

    using (var context = new MyDbContext())
    {
        fixture.Inject(context);
        var entity = fixture.CreateAnonymous<MyEntity>();
        context.Set<MyEntity>().Add(entity);
        context.SaveChanges();
    }
}

[TestMethod]    
[ExpectedException(typeof(InvalidOperationException))]
public void AutoFixtureMyEntityEntityWithoutInjection()
{
    var fixture = new Fixture();

    fixture.Customize<MyEntity>(
       c => c.FromFactory<MyDbContext>(ctx => ctx.Set<MyEntity>().Create()));

    using (var context = new MyDbContext())
    {
        var entity = fixture.CreateAnonymous<MyEntity>();
        context.Set<MyEntity>().Add(entity);
        context.SaveChanges();
    }
}

Obviously, that isn't working since CreateAnonymous() isn't expecting the input parameter for the factory. I can only assume that i have a flawed understanding of what FromFactory() provides. Although the comment reads,

/// Specifies that a specimen should be created in a particular way, using a single input
/// parameter for the factory.

After reading ploehs blog, I'm slightly more confused on how these pieces interact with each other.

The instance of MyDbContext during factory invocation is not the instance I passed to Inject()

Was it helpful?

Solution

Would something like this work?

var fixture = new Fixture();
fixture.Customize<MyEntity>(c => c
    .FromFactory<MyDbContext, MyEntity>(ctx => ctx.Set<MyEntity>.Create()));

using (var context = new MyDbContext())
{
    fixture.Inject(context);
    var item = fixture.CreateAnonymous<MyEntity>();
    context.Set<MyEntity>().Add(item);
    context.SaveChanges();
}

Disclaimer: I haven't tried to compile this...


FWIW, if you were using xUnit.net with AutoFixture, you could reduce the test to something like:

[Theory, MyAutoData]
public void TheTest([Frozen]MyDbContext context, MyEntity item)
{
    context.Set<MyEntity>().Add(item);
    context.SaveChanges();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top