Question

I'm new to mocks and am deciding on a mock framework. The Moq home quotes

Currently, it's the only mocking library that goes against the generalized and somewhat unintuitive (especially for novices) Record/Reply approach from all other frameworks.

Can anyone explain simply what the Record/Replay approach is and how Moq differs? What are the pros and cons of each especially from the point of deciding a framework?

Thanks.

Was it helpful?

Solution

The Record/Replay approach is supported by RhinoMocks. The basic idea is that your test execution is divided into two phases, the record phase and the replay phase. To be a little bit more concrete

var repo = new MockRepository();
var dependency = repo.DynamicMock<IDependency>();
With.Mocks(repo).Expecting(delegate {
         Expect.Call(dependency.AMethod(1)).Return(result);                    
      }).Verify(delegate {
         var sut = new Sut(wrappee);
         sut.DoStuffThatCallsAMethod();
         Assert.IsTrue(sut.ResultState);
      });

So the Expecting block is the Record phase and the Verify block is the Replay phase.

The Moq variant of this code would be

var dependency = new Mock<IDependency>();
dependency.Expect(dep => dep.AMethod(1)).Returns(result);          
var sut = new Sut(wrappee.Object);
sut.DoStuffThatCallsAMethod();
Assert.IsTrue(sut.ResultState);

Which as you can see is much nicer to read. I used to use RhinoMocks but since I discovered Moq I only use Moq. I find it to be produce much more readable code. So my advice would be to go for Moq.

OTHER TIPS

RhinoMocks is actually very versatile, you can use either approach. RhinoMocks looks a bit better than Moq under the expect/verify style. However, even the fact that you can use this style is buried in the documentation (last time i looked). We picked Moq over RhinoMocks on my current project because we didn't realise that it does setup/verify.

The record / replay syntax does give you the ability to change the value that a method will return on subsequent calls to that method. This can be useful sometimes. Having said that, the need to do this is often a smell that your design isn't quite right. It's useful though when you can quite see what is wrong and you have to move on.

Moq does have the ability to change the value but it's somewhat clunky (from the documentation)

// returning different values on each invocation 
var mock = new Mock<IFoo>(); 
var calls = 0; 
mock.Setup(foo => foo.GetCountThing())
.Returns(() => calls)
.Callback(() => calls++); 

I've gone right off Record/Replay because it makes it hard to see in the setup what's stubbed/mocked or just running code. I believe that Rhino has multiple ways of working. In particular, you can use a using() block to isolate setup from other calls.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top