Rhino Mocks Isn't Complicated

- select the contributor at the end of the page -
I've heard multiple people state that they prefer Moq over Rhino Mocks because the Rhino Mocks syntax isn't as clean. And while I don't have a strong preference between the two, 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.

Get our content first. In your inbox.

Loading form...

If this message remains, it may be due to cookies being disabled or to an ad blocker.

Contributor

Jim Cooper

Jim Cooper is a software developer at Pluralsight, with more than 20 years of software development experience. He has a passion for Agile processes, especially lean software development. Jim has been developing production Angular apps since before Angular version 1.0, including Pluralsight's first Html5-based video player. Jim has over 10 years of TDD and pair programming experience which has contributed significantly to his professional development. He has successfully mentored other developers in the use of TDD and agile practices and still enjoys learning from talented developers everywhere.