My previous post about AutoFixture’s Freeze functionality included this little piece of code that I didn’t discuss:
var mapMock = new Mock<IPizzaMap>();
fixture.Register(mapMock.Object);
In case you were wondering, this is Moq interacting with AutoFixture. Here we create a new Test Double and register it with the fixture. This is very similar to AutoFixture’s built-in Freeze functionality, with the difference that we register an IPizzaMap instance, which isn’t the same as the Mock<IPizzaMap> instance.
It would be nice if we could simply freeze a Test Double emitted by Moq, but unfortunately we can’t directly use the Freeze method, since Freeze<Mock<IPizzaMap>>() would freeze a Mock<IPizzaMap>, but not IPizzaMap itself. On the other hand, Freeze<IPizzaMap>() wouldn’t work because we haven’t told the fixture how to create IPizzaMap instances, but even if we had, we wouldn’t have a Mock<IPizzaMap> against which we could call Verify.
On the other hand, it’s trivial to write an extension method to Fixture:
public static Mock<T> FreezeMoq<T>(this Fixture fixture)
where T : class
{
var td = new Mock<T>();
fixture.Register(td.Object);
return td;
}
I chose to call the method FreezeMoq to indicate its affinity with Moq.
We can now rewrite the unit test from the previous post like this:
[TestMethod]
public void AddWillPipeMapCorrectly_FreezeMoq()
// Fixture setup
var fixture = new Fixture();
var basket = fixture.Freeze<Basket>();
var mapMock = fixture.FreezeMoq<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
You may think that saving only a single line of code may not be that big a deal, but if you also need to perform Setups on the Mock, or if you have several different Mocks to configure, you may appreciate the encapsulation. I know I sure do.
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Saturday, February 04, 2012 9:49:57 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.