Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using autofixture in my data integration tests to create proxies

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()

like image 315
AndrewBoudreau Avatar asked Jan 18 '13 01:01

AndrewBoudreau


1 Answers

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();
}
like image 103
Mark Seemann Avatar answered Sep 18 '22 14:09

Mark Seemann