NSubstitute vs Moq - a quick comparison

Posted on Mon 27 February 2012 in Coding

When you write unit tests, you occasionally need to mock away dependencies of the subject under test (SUT). By far the easiest way to do this is to use a mocking library, which has the added benefit that it allows you to verify the behavior of the SUT by inspecting its interaction with the mock. I’ve used EasyMock for Java quite a lot, but one of its drawbacks, one that it shares with many other mocking libraries, is that it uses a record/replay pattern, which leads to a test case on the following form:

  1. Setup mock response behavior and expectations.
  2. Put the mock object into replay mode.
  3. Do something with the SUT (this should be the meat of the test, really).
  4. Verify that all mock expectations were met, in one go.

Even with only a modest number of expectations, a test case on this form easily becomes front-heavy, and the SUT interaction may be drowned out. Another big problem is that the form does not lend itself well to a context/specification style of testing. Using that style, you have a single context setup (including SUT interaction) and multiple specifications (tests). Thus, you’d want to verify individual mock calls for each specification rather than verifying all expectations at once.

When I first encountered Moq, a mocking library for .NET, I was pleased to find that it allows me to verify individual mock calls, which completely eradicates the need of defining expectations. As a result, I can specify mock response behavior in the context setup, and verify how the SUT interacts with the mock in the specifications (tests). There is also no need to separate record and replay modes. Nice!

However, after having used Moq for a while in a VB.NET project, I feel that its syntax is a bit too noisy (perhaps this is partly the fault of VB.NET, which in itself is much noisier than C#). And even though its use of lambdas is neat, I’m not sure it’s best for readability. Searching for alternatives, I came across NSubstitute, and I immediately felt that this was what I was looking for!

NSubstitute has, IMHO, a much cleaner syntax than Moq, and it supports the context/specification style out of the box. Below is a quick comparison between the two. I’ve only tested a few aspects so far, but NSubsitute feels a lot better!

Comparing the two

Let’s say that we have an interface for some sort of quiz engine. It’s pretty simple; when there are numbers available, it raises an event. A quiz solver can then read the numbers, sum them and provide the sum to the quiz engine.

Public Interface IQuiz
    Event HasNumbers As Action
    ReadOnly Property Numbers As IEnumerable(Of Integer)

    Sub SumIs(sum As Integer)
End Interface

To test the summing capability of a quiz solver, let’s use a quiz engine mock! First, the mock creation:

' Moq
Dim quizMock = New Mock(Of IQuiz)()

' NSubstitute
Dim quiz = Substitute.For(Of IQuiz)()

Not a huge difference, but I think NSubstitute is a bit more readable! What’s not visible from this, but which becomes obvious later on, is that the type of quizMock is Mock(Of IQuiz), whereas the type of quiz is IQuiz. Next, let’s define some mock response behavior. Specifically, we want our Numbers property to return the numbers 1, 2 and 3:

' Moq
quizMock.SetupGet(Function(quiz) quiz.Numbers).Returns({1, 2, 3})

' NSubstitute
quiz.Numbers.Returns({1, 2, 3})

Now the difference is much bigger. With Moq, we have to call a special SetupGet method on the mock, and pass a lambda that represents the call for which we want to specify a behavior (internally, the lambda becomes an expression tree that Moq parses). Contrast that with the straight-forward syntax of NSubsitute (where Returns is an extension method). A clear win for NSubstitute, I think!

Now it’s time to make our SUT (the construction of which I have omitted because it has nothing to do with the choice of mocking library, obviously) do its work, and since it’s triggered by an event, we need to raise the event on the mock:

' Moq
quizMock.Raise(Sub(quiz) AddHandler quiz.HasNumbers, Nothing)

' NSubstitute
AddHandler quiz.HasNumbers, Raise.Event(Of Action)()

Not a big difference, although the Nothing argument required to represent an event handler in the Moq case can be confusing - and even more so if the event is parameterized. The AddHandler syntax of VB.NET is pretty noisy and there’s not much a mocking library can do to overcome that.

Finally, let’s verify that the solver sums the numbers correctly:

' Moq
quizMock.Verify(Sub(quiz) quiz.SumIs(6))

' NSubstitute

Again, I think NSubsitute comes out as winner since its syntax is less cumbersome and more “on the spot”. In this case, the argument matching process is simple and handled automatically by both mocking libraries. With more complex arguments (lists, for example), we may need to use more sophisticated argument matching, which reads roughly the same in both libraries.

The overall verdict? I really like NSubstitute over Moq due to its more readable syntax!

A note on event handlers and VB.NET

In VB.NET, an event can be defined without an event handler type. So for example, the HasNumbers event in our IQuiz interface could be defined as:

Public Interface IQuiz
    Event HasNumbers()
End Interface

NSubstitute doesn’t like this, though, because there is no Raise.Event method overload that can be converted to the anonymous event handler type that is created. Therefore, you have to specify the event handler type of the event explicitly, as we did previously.