Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

24 Mar 2009

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.