Strict mocks lead to overspecification

Here is an example that demonstrates how strick mocks lead to overspecification. Imagine that we are creating a simple screen in a Passive View architecture. The first feature that we implement is displaying the message “edit” when the user clicks the edit button:

[Fact] public void ShouldDisplayEditClickMessage()
{
 // Establish context
 MockRepository mockRepository = new MockRepository();
 IView view = mockRepository.StrictMock<IView>();
 Expect.Call(delegate { view.EditClick += null; }).IgnoreArguments();
 mockRepository.Replay(view);

 // Create sut
 Presenter sut = new Presenter(view);

 // Setup expectations
 mockRepository.BackToRecord(view, BackToRecordOptions.Expectations);
 Expect.Call(delegate { view.DisplayClickMessage("edit"); });
 mockRepository.ReplayAll();

 // Exercise
 RhinoMocksExtensions
  .GetEventRaiser(view, delegate(IView v) { v.EditClick += null; })
  .Raise(view, EventArgs.Empty);

 // Verify
 mockRepository.VerifyAll();
}

screenshot of test runner with all tests passing

And now we add the feature that displays the message “save” whenever the user clicks on the save button:

[Fact] public void ShouldDisplaySaveClickMessage()
{
 // Establish context
 MockRepository mockRepository = new MockRepository();
 IView view = mockRepository.StrictMock<IView>();
 Expect.Call(delegate { view.EditClick += null; }).IgnoreArguments();
 Expect.Call(delegate { view.SaveClick += null; }).IgnoreArguments();
 mockRepository.Replay(view);

 // Create sut
 Presenter sut = new Presenter(view);

 // Setup expectations
 mockRepository.BackToRecord(view, BackToRecordOptions.Expectations);
 Expect.Call(delegate { view.DisplayClickMessage("save"); });
 mockRepository.ReplayAll();

 // Exercise
 RhinoMocksExtensions
  .GetEventRaiser(view, delegate(IView v) { v.SaveClick += null; })
  .Raise(view, EventArgs.Empty);

  // Verify
  mockRepository.VerifyAll();
 }
}

screenshot of test runner with a failing test.

Although we implemented the feature correctly, and left the code of the first feature untouched, we notice that our ShouldDisplayEditClickMessage test fails because it is not expecting a subscription to the SaveClick event. Imho, this way of testing is a testing anti-pattern.

This entry was posted on Tuesday, March 24th, 2009 at 16:49 and is filed under C#, Patterns. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

Comments are closed.