Comparing Moq to Rhino Mocks

So which mocking framework should we use? Do we fall back on good old Rhino Mocks or do we choose for the new kid on the block Moq?

From a technical point of view i would dare to say that they will be able to support the same set of features because they’re both based on Castle’s DynamicProxy. Rhino Mocks has the advantages that it, unlike Moq, supports the mocking of Delegates and can be used in a .Net 2.0 only environment. Whether or not we should care about these differences is a question i will leave unanswered.

From a user point of view i find the Moq API a bit cleaner because it frees me from thinking about the record-replay model and Rhino Mocks wants me to make assertions on a stub. Apart from that the differences are rather small given for the use-cases i presented in Getting started with Moq.

  • Creating instances:
    // Rhino
    var productDetailView = MockRepository.GenerateStub<iproductDetailView>();


    // Moq
    var productDetailViewMock = new Mock<iproductDetailView>();
  • Setting up results:
    // Rhino Mocks
    productRepository
      .Stub(repository => repository.GetCategory(0)).IgnoreArguments()
      .Do((Delegates.Function<icategory, int>)(categoryId => return category;));


    // Moq
    productRepositoryMock
      .Setup(repository => repository.GetCategory(It.IsAny<int>()))
      .Returns<int>(categoryId => return category.Object;});
  • Consuming the mocked objects:
    // Rhino Mocks
    // Nothing to do


    // Moq
    // Nothing to do
  • Raising events:
    // Rhino Mocks
    productDetailView.Raise(view => view.EditClick += null).Raise(sender, EventArgs.Empty);


    // Moq
    productDetailViewMock.Raise(view => view.EditClick += null, sender, EventArgs.Empty);
  • Verifying that a method was invoked:
    // Rhino Mocks - Odd that i'm asserting on a Stub.
    productRepository.AssertWasCalled(
      repository => repository.FindCategories(
        Arg<ispecification<icategory>>.Matches(Is.TypeOf(typeof(All<icategory>)))));


    // Moq
    productRepositoryMock.Verify(
      repository => repository.FindCategories(
        It.Is<ispecification<icategory>>(specification => specification.GetType() == typeof(All<icategory>))));
  • Override a result
    // Rhino Mocks
    productDetailView.BackToRecord();
    
    productDetailView
      .Stub(view => view.CategoryId)
      .Returns(2);


    // Moq
    productDetailViewMock
      .Setup(view => view.CategoryId).Returns(2);

Editted code to take advantage of the new AAA syntax that comes with Rhino Mocks 3.5 If only someone could show me how i can override a Stubbed result…

Leave a comment ?

12 Comments.

  1. What about comparing Moq with a new AAA capable syntax was introduced in the Rhino.Mocks 3.5?

  2. Hi Tim,

    You might prefer Rhino Mocks’ AAA syntax. You don’t need to use record/replay then, and it makes stubbing results and creating mocks much easier, (very much like the Moq approach).

    Rhino Mocks also supports the same event raising syntax as Moq.

    Regards,
    David

  3. As shown in the updated code snippets, the new API is considerable cleaner… But i don’t know how i can change a stubbed result in a clean way.

  4. Here’s my attempt at some examples. Haven’t compiled or tested them, but they should be close.

    Example of stubbing return values:
    var productDetailView = MockRepository.GenerateStub();
    productDetailView
    .Stub(view => view.GetCategory(Arg.Is.Anything()))
    .Return(category);

    Example of setting property on stubs:
    var productDetailView = MockRepository.GenerateStub();
    productDetailView.CategoryId = 2; // Stubs have PropertyBehavior by default, so can use them as normal properties

    Hope this helps. (For the record, I’ve mainly used Rhino Mocks, but quite like Moq too :) ).
    – David

  5. @David: The inital stubbing is easy.. But changing it later on is something which i can’t figure out.

    productDetailView
    .Stub(view => GetCategory(0))
    .Return(null);
    
    // When i add productDetailView.BackToRecord it does work.
    // But that would mean that i have to mess with the record-replay model :/
    
    productDetailView
    .Stub(view => view.GetCategory(0))
    .Throw(new Exception());
  6. Hi Tim,

    Is this what you mean?

    [Test]
    public void Stub_with_multiple_calls() {
    var productDetailView = MockRepository.GenerateStub();
    productDetailView.Stub(s => s.GetCategory()).Return(1).Repeat.Once();
    Assert.That(productDetailView.GetCategory(), Is.EqualTo(1));

    productDetailView.Stub(s => s.GetCategory()).Return(2);
    Assert.That(productDetailView.GetCategory(), Is.EqualTo(2));
    }

    I find the repeat stuff a bit confusing and tend to avoid it in favour of simpler tests where possible.

    If you are talking about queuing up multiple results before performing any actions then I don’t know how to do that. I know this post is intended as a quick comparison, but if you are interested in following up some of the Rhino Mocks questions the Rhino Mocks Google group is quite good: http://groups.google.com/group/RhinoMocks.

    Regards,
    David

  7. @David:

    That is not what i mean. What i mean is the following:

    class BehaviorInAHappyPathContext
    {
    virtual void Given() { // Stub a result }
    }

    class BehaviorInAOneBadPropertyContext : BehaviorInAHappyPathContext
    {
    override void Given()
    {
    base.Given();

    // inject the bad variable
    // requires me to Stub a different result for the same method.
    // seems impossible without a BackToRecord call.
    }
    }[/code]

  8. @David:

    For the queing of calls i have found a rather clean solution (here) by using a Queue of callback methods.

  9. Oh I see. You can use Repeat.Any() to override results stubbed out in the Given() method.

    E.g.:

    [Test]
    public void Stub_with_multiple_calls()
    {
    var productDetailView = MockRepository.GenerateStub();
    productDetailView.Stub(s => s.GetCategory()).Return(1);
    productDetailView.Stub(s => s.GetCategory()).Return(2).Repeat.Any();
    Assert.That(productDetailView.GetCategory(), Is.EqualTo(2));
    }

    That’s provided you don’t use Repeat.Any() when you initially stubbed the result.

  10. @David:

    Ok, that seems to work.

    (I don’t care about supporting more than one level of inheritance in a test fixture because i’ve experienced how it becomes a maintenance nightmare)

  11. Great. By the way, I noticed in your previous comment you mentioned using Context/Given() for your tests. I would love to read a post on how you are using that style. :) I’ve been toying around with different approaches but haven’t found one that works for me yet.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackbacks and Pingbacks: