Daniel Cazzulino's Blog : What's wrong with the Record/Reply/Verify model for mocking frameworks

Subscriptions

<May 2008>
SuMoTuWeThFrSa
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

  Microsoft MVP Profile

News

 

 Contact

Post Categories

What's wrong with the Record/Reply/Verify model for mocking frameworks

Most mocking frameworks, and especially the two most popular ones, Rhino Mocks and TypeMock, use a record/reply/verify model where the developer invokes members on the mock during the record phase, does a replay to prepare the mock for those expectations, and finally do a verify before the test ends.

From Rhino documentation (emphasis mine):

Record & Replay model - a model that allows for recording actions on a mock object and then replaying and verifying them. All mocking frameworks uses this model. Some (NMock, TypeMock.Net, NMock2) use it implicitly and some (EasyMock.Net, Rhino Mocks) use it explicitly.

Well, it's not true anymore that *all" mocking frameworks use record/replay :).

Anyway, an example from Rhino is:

[Test]
public void SaveProjectAs_CanBeCanceled()
{
  MockRepository mocks = new MockRepository();
  IProjectView projectView = (IProjectView)mocks .CreateMock(typeof(IProjectView));
  Project prj = new Project("Example Project");
  IProjectPresenter presenter = new ProjectPresenter(prj,projectView);
  Expect.Call(projectView.Title).Return(prj.Name);
  Expect.Call(projectView.Ask(question,answer)).Return(null);
  mocks.ReplayAll();
  Assert.IsFalse(presenter.SaveProjectAs());          
  mocks.VerifyAll();
}

I find this record/replay/verify model somewhat unnatural. When you follow the typical progression explained in Mocks, Stubs and Fakes: it's a continuum, you end up thinking about your mocks as invokers of your delegates/lambdas. There's no especial concept to understand. It's "plain .NET" if you will. The above test in MoQ (which is the result of taking that very progression and turning it into a generic mock framework) looks like the following:

[Test]
public void SaveProjectAs_CanBeCanceled()
{
    string question, answer;
    var projectView = new Mock<IProjectView>();
    var prj = new Project("Example Project");
    var presenter = new ProjectPresenter(prj, projectView.Object);
    
    projectView.Expect(x => x.Title).Returns(prj.Name);
    projectView.Expect(x => x.Ask(question, answer)).Returns(null);
    
    Assert.IsFalse(presenter.SaveProjectAs());
}

Note that the only assertion is the one on the presenter.SaveProjectAs. There are absolutely no "side effects" from using the mock framework. It's just a helper for your traditional state/classic test. And MoQ is mostly syntactic sugar for what you could have done yourself.

Verifying the mock slowly but almost inevitably takes you down the path of focusing your tests in the interaction as opposed to the state of the object under test. I agree with mockists that sometimes an interaction test is the only way to ensure a given behavior (cache hits/misses is the most evident one), but it's more of the exception than the rule IMO.

That's why MoQ doesn't provide a Verify method on its Mock<T> class. I strongly believe that an API that makes it very easy for you to do the "right thing" is the way to go. You can still verify the interactions with MoQ, but it's going to be a bit more work, keeping flags of invoked members and setting them from callbacks. This way, the mocking framework takes you away from that kind of testing by making it more difficult.

posted on Wednesday, December 26, 2007 4:20 AM by kzu

# What's wrong with the Record/Reply/Verify model for mocking frameworks @ Wednesday, December 26, 2007 4:42 AM

Most mocking frameworks, and especially the two most popular ones, Rhino Mocks and TypeMock , use a record

Anonymous

# The Record/Replay/Verify model @ Wednesday, December 26, 2007 1:45 PM

The Record/Replay/Verify model

Anonymous

# Contribuciones realizadas por MVPs en Diciembre @ Tuesday, January 15, 2008 10:19 AM

Hola Quiero compartir con todos, estas excelentes contribuciones que han realizado los MVPs en el mes

Anonymous

# Contribuciones realizadas por MVPs en Diciembre @ Tuesday, January 15, 2008 11:13 AM

Hola Quiero compartir con todos, estas excelentes contribuciones que han realizado los MVPs en el mes

Anonymous

# New Moq features for mock verification and creation @ Saturday, February 02, 2008 6:53 PM

I wrote before about What's wrong with the Record/Reply/Verify model for mocking frameworks , and in

Anonymous

# Unit testing, playing tennis, and the lack of absolutes in TDD @ Monday, March 03, 2008 5:05 AM

I&amp;#39;m not a particularly good tennis player. Mostly from not having played in years, but even then

Anonymous

# A Gentle Introduction to Mocking @ Thursday, April 17, 2008 4:19 PM

At the last CMAP Code Camp I did a &quot;code-only&quot; presentation entitled &quot;A Gentle Introduction to Mocking&quot;....

Anonymous

# A Gentle Introduction to Mocking @ Thursday, April 17, 2008 4:27 PM

At the last CMAP Code Camp I did a &quot;code-only&quot; presentation entitled &quot;A Gentle Introduction to Mocking&quot;.

Anonymous