Replacing Rhino with Moq
We’re just starting down the path of serious and extensive testing with mocks and fakes. Our initial tests were all done using Rhino Mocks, mostly because it had a well established reputation and we had no reason not to give it a try. The syntax is beautiful and did everything we needed, until we tried to make a test similar to this one pass successfully.
public interface IFoo
{
string Bar();
}
[Fact] public void TestWithRhino()
{
var mock = MockRepository.GenerateStub<IFoo>();
mock.Stub(x => x.Bar()).Return("bar");
mock.Stub(x => x.Bar()).Return("baz");
Assert.Equal("baz",mock.Bar());
}
We couldn’t, at least we couldn’t using strictly stubs. From what I could gather, we could if we used a more complicated for of mocking besides stubs. We only need stubs, or fakes, because we don’t need to test all the interaction, just the ending state.
Since we don’t have any serious stock in using Rhino, as an alternative I decided to take a look at using Moq. The syntax for Moq is not as nice. It is more wordy, but I do like how it doesn’t rely on extensions methods for everything. But what about the sample test?
[Fact] public void TestWithMoq()
{
var mock = new Mock<IFoo>();
mock.Setup(x => x.Bar()).Returns("bar");
mock.Setup(x => x.Bar()).Returns("baz");
Assert.Equal("baz", mock.Object.Bar());
}
It passes! Switching wasn’t that difficult, but where is the ugly syntax I‘ve run into so far? Well this in Rhino:
MockOrdersRepository.AssertWasNotCalled(x=>x.StartOrder(null,null,null,null));
…becomes this in Moq:
MockOrdersRepository .Verify(x=>x.StartOrder( It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never());
It might be I am not familiar enough with either to say that is the equivalent assertion of both, but it is working for us. I am probably missing something that is causing Moq to look more verbose.
Comments(2)
I don’t think you’ll regret it. I find Moq elegant.
See this thread on Stack Overflow for more info:
http://stackoverflow.com/questions/1718463/what-are-the-real-world-pros-and-cons-of-each-of-the-major-mocking-frameworks/1719391
@Bill The only thing that is kinda painful so far is not mocking delegates. We are having to do a lot of It.IsAny>() to mock x=>x.value == “foo”, and that is no where near safe, but mocking delegates in general is pretty hard.
We’ve been happy with it so far.