Thursday, July 5, 2012

Rhino Mocks Isn't Complicated

I've heard multiple people state that they prefer Moq over Rhino Mocks because the Rhino Mocks syntax isn't as clean. I'd like to help dispel that myth. It is true that, if you choose the wrong syntax, Rhino can be more complicated. This is because Rhino has been around for a while and it's original syntax pre-dates the improved Arrange/Act/Assert syntax. I go into a lot more detail on Rhino Mocks and the appropriate way to use it in my new Pluralisight Course on Rhino Mocks, but to dispel the myth that Rhino Mocks is complicated I would like to compare the syntax for creating stubs and mocks using Rhino vs. Moq:

Moq Syntax:
  //Arrange
  var mockUserRepository= new Mock<IUserRepository>();
  var classUnderTest = new ClassToTest(mockUserRepository.object);
  mockUserRepository
      .Setup(x => x.GetUserByName("user-name"))
      .Returns(new User());

  //Act
  classUnderTest.MethodUnderTest();

  //Assert
  mockUserRepository
      .Verify(x => x.GetUserByName("user-name"));
Rhino Stub Syntax:
  //Arrange
  var mockUserRepository=MockRepository.GenerateMock<IUserRepository>();
  var classUnderTest = new ClassToTest(mockUserRepository);
  mockUserRepository
      .Stub(x => x.GetUserByName("user-name"))
      .Returns(new User());

  //Act
  classUnderTest.MethodUnderTest();

  //Assert
  mockUserRepository
      .AssertWasCalled(x => x.GetUserByName("user-name"));
Notice that there are only four differences in those examples: the use of "new Mock" instead of MockRepository, the term Setup vs. Stub and the term Verify vs. AssertWasCalled and the need to call ".Object" on the mock object when using Moq. So why do so many people think Rhino Mocks more complicated? Because of it's older Record/Replay syntax which required code like the following:

using ( mocks.Record() )
{
    Expect
        .Call( mockUserRepository.GetUserByName("user-name) )
        .Returns( new User() );
}

using ( mocks.Playback() )
{
    var classUnderTest = new ClassUnderTest(mockUserRepository);
    classUnderTest .TestMethod();
}
There is also another benefit of using Rhino Mocks. The support for Rhino by StructureMap AutoMocker is cleaner due to the fact that the mocks returned by Rhino are actual implementations of the interface being mocked rather than a wrapper around the implementation which is what Moq provides. AutoMocker allows you to abstract away the construction of the class under test so that your tests aren't coupled to the constructors of the class under test. This reduces refactoring tension when new dependencies are added to your classes. It also cleans up your tests a bit when you have a number of dependencies. If you haven't used AutoMocker, you can quickly learn how it works by checking out the AutoMocker module in my Pluralsight Rhino Mocks video. But here is a quick comparison of using AutoMocker with Moq vs. Rhino:

Moq syntax using MoqAutoMocker:
//Arrange
var autoMocker = new MoqAutoMocker();
  Mock.Get(autoMocker.Get<IUserRepository>())
      .Setup(x => x.GetUserByName("user-name"))
      .Returns(new User());

  //Act
  autoMocker.ClassUnderTest.MethodUnderTest();

  //Assert
  Mock.Get(autoMocker.Get<IUserRepository>())
      .Verify(x => x.GetUserByName("user-name"));
Rhino syntax using RhinoAutoMocker:
//Arrange
var autoMocker = new RhinoAutoMocker<ClassUnderTest>();
  autoMocker.Get<IUserRepository>();
      .Setup(x => x.GetUserByName("user-name"))
      .Returns(new User());

  //Act
  autoMocker.ClassUnderTest.MethodUnderTest();

  //Assert
  autoMocker.Get<IUserRepository>();
      .AssertWasCalled(x => x.GetUserByName("user-name"));
I hope that this clarifies, for some, the correct way to use Rhino Mocks and illustrates that it is every bit as simple as Moq when used correctly.