The new internal architecture of AutoFixture 2.0 enables some interesting features. One of these is that it becomes easy to extend AutoFixture to become an auto-mocking container.
Since I personally use Moq, the AutoFixture 2.0 .zip file includes a new assembly called Ploeh.AutoFixture.AutoMoq that includes an auto-mocking extension that uses Moq for Test Doubles.
Please note that AutoFixture in itself has no dependency on Moq. If you don’t want to use Moq, you can just ignore the Ploeh.AutoFixture.AutoMoq assembly. Auto-mocking with AutoFixture does not have to use Moq. Although it only ships with Moq support, it is possible to write an auto-mocking extension for a different dynamic mock library.
Please note that AutoFixture in itself has no dependency on Moq. If you don’t want to use Moq, you can just ignore the Ploeh.AutoFixture.AutoMoq assembly.
Auto-mocking with AutoFixture does not have to use Moq. Although it only ships with Moq support, it is possible to write an auto-mocking extension for a different dynamic mock library.
To use it, you must first add a reference to Ploeh.AutoFixture.AutoMoq. You can now create your Fixture instance like this:
var fixture = new Fixture()
.Customize(new AutoMoqCustomization());
What this does is that it adds a fallback mechanism to the fixture. If a type falls through the normal engine without being handled, the auto-mocking extension will check whether it is a request for an interface or abstract class. If this is so, it will relay the request to a request for a Mock of the same type.
A different part of the extension handles requests for Mocks, which ensures that the Mock will be created and returned.
Splitting up auto-mocking into a relay and a creational strategy for Mock objects proper also means that we can directly request a Mock if we would like that. Even better, we can use the built-in Freeze support to freeze a Mock, and it will also automatically freeze the auto-mocked instance as well (because the relay will ask for a Mock that turns out to be frozen).
Returning to the original frozen pizza example, we can now rewrite it like this:
[Fact]
public void AddWillPipeMapCorrectly()
{
// Fixture setup
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 that we can simply freeze Mock<IPizzaMap> which also automatically freeze the IPizzaMap instance as well. When we later create the SUT by requesting an anonymous BasketPresenter, IPizzaMap is already frozen in the fixture, so the correct instance will be injected into the SUT.
This is similar to the behavior of the custom FreezeMoq extension method I previously described, but now this feature is baked in.
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Saturday, February 04, 2012 7:54:24 PM (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.