Yet Another .NET Mocking Framework

By | August 19, 2010

That’s right, yet another .NET mocking framework. Given that my team is making the transition from NMock to Moq for a variety of reasons, I most definitely wasn’t looking for another such framework. Then I read one of Roy Osherove’s tweets:

whatStartedIt

Pretty compelling statement coming from Roy, and in light of my recent conversion to Moq, I figured the earlier I check this out, the better.

We’ll be using the same code base in the above cited post for our comparison.

Moq, Again

The Moq version of our example is shown below again.

[Test]
public void SomeBizCountIsLazyLoadedTest3()
{
    Mock<IBizRepo> mockRepo = new Mock<IBizRepo>();
    mockRepo.Setup(m => m.GetSomeCount("bizobjectname")).Returns(42);

    BizObject b = new BizObject("bizobjectname", mockRepo.Object);

    Assert.That(b.SomeBizCount, Is.EqualTo(42));
    mockRepo.Verify(m => m.GetSomeCount("bizobjectname"), Times.Exactly(1));
}

Remember that the compelling reason to switch from NMock to Moq was the elimination of magic strings for the methods and properties that were being mocked, and the more natural way of expressing what methods and properties we expected to be called on our mocks at the end of the test.

Enter FakeItEasy

Now let’s see what this same mock looks like in FakeItEasy. To do this, we first have to download the latest version, which can be found here. Once downloaded, we extract the contents, copy FakeItEasy.dll into our ReferencedDLLs folder, and add a reference.

fakeItEasyAdded

With the library added, we can rewrite our above test using FakeItEasy’s new syntax.

[Test]
public void SomeBizCountIsLazyLoadedTest4()
{
    IBizRepo mockRepo = A.Fake<IBizRepo>();
    A.CallTo(() => mockRepo.GetSomeCount("bizobjectname")).Returns(42);

    BizObject b = new BizObject("bizobjectname", mockRepo);

    Assert.That(b.SomeBizCount, Is.EqualTo(42));
    A.CallTo(() => mockRepo.GetSomeCount("bizobjectname"))
        .MustHaveHappened(Repeated.Once);
}

While not much different, it does read a bit more fluently, which my team likes. Is it compelling enough to switch? Not just based on this. Let’s look at how the error messages help us though. To do this, we’ll change the implementation of BizObject to not make the GetSomeCount call we expect. First, the Moq error message.

moqErrorMessage

And next the FakeItEasy error message.

fakeItEasyErrorMessage

Eh. More white space and a slightly less terse delivery makes the FakeItEasy error message a bit more pleasing and readable to the eye.

Conclusion

Is this enough to switch? Not with religious fervor, but we haven’t really deep-dived into the mocking features. I’ll open up the floor up to some experimentation in our projects so we can see how the FakeItEasy approach pans out in some real code; if we find anything compellingly interesting, I’ll make sure to write about it.