AutoFixture 2.0 comes with a new extension for xUnit.net data theories. For those of us using xUnit.net, it can help make our unit tests more succinct and declarative.
AutoFixture’s support for xUnit.net is implemented in a separate assembly. AutoFixture itself has no dependency on xUnit.net, and if you use another unit testing framework, you can just ignore the existence of the Ploeh.AutoFixture.Xunit assembly.
Let’s go back and revisit the previous test we wrote using AutoFixture and its auto-mocking extension:
[Fact]
public void AddWillPipeMapCorrectly()
{
// Fixture setup
var fixture = new Fixture()
.Customize(new AutoMoqCustomization());
var basket = fixture.Freeze<Basket>();
var mapMock = fixture.Freeze<Mock<IPizzaMap>>();
var pizza = fixture.CreateAnonymous<PizzaPresenter>();
var sut = fixture.CreateAnonymous<BasketPresenter>();
// Exercise system
sut.Add(pizza);
// Verify outcome
mapMock.Verify(m => m.Pipe(pizza, basket.Add));
// Teardown
}
Notice how all of the Fixture Setup phase is only used to create various objects that will be used in the test. First we create the fixture object, and then we use it to create four other objects. That turns out to be a pretty common idiom when using AutoFixture, so it’s worthwhile to reduce the clutter if possible.
With xUnit.net’s excellent extensibility features, we can. AutoFixture 2.0 now includes the AutoDataAttribute in a separate assembly. AutoDataAttribute derives from xUnit.net’s DataAttribute (just like InlineDataAttribute), and while we can use it as is, it becomes really powerful if we combine it with auto-mocking like this:
public class AutoMoqDataAttribute : AutoDataAttribute
public AutoMoqDataAttribute()
: base(new Fixture()
.Customize(new AutoMoqCustomization()))
This is a custom attribute that combines AutoFixture’s two optional extensions for auto-mocking and xUnit.net support. With the AutoMoqDataAttribute in place, we can now rewrite the above test like this:
[Theory, AutoMoqData]
public void AddWillPipeMapCorrectly([Frozen]Basket basket,
[Frozen]Mock<IPizzaMap> mapMock, PizzaPresenter pizza,
BasketPresenter sut)
The AutoDataAttribute simply uses a Fixture object to create the objects declared in the unit tests parameter list. Notice that the test is no longer a [Fact], but rather a [Theory].
The only slightly tricky thing to notice is that when we declare a parameter object, it will automatically map to a call to the CreateAnonymous method for the parameter type. However, when we need to invoke the Freeze method, we can add the [Frozen] attribute in front of the parameter.
The best part about data theories is that they don’t prevent us from writing normal unit tests in the same Test Class, and this carries over to the [AutoData] attribute. We can use it when it’s possible, but for those more complex tests where we need to interact with a Fixture instance, we can still write a normal [Fact].
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Thursday, February 23, 2012 4:55:29 AM (Romance Standard Time, UTC+01:00)
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.