Simplifying Rhino.Mocks, Round III: kinds of mocks

My last two posts regarding Rhino.Mocks, attracted quite a lot of attention. Focusing on solution I proposed for limiting complexity around creation different kinds of mocks, one thing was pointed out by few people as not the best solution. Ayende called it “in your face! API design”, that is stating the kind of mock you want to create explicitly, via method parameter.

I don’t think that doing it via method name is any less explicit, but let’s not go there. Instead, let’s think for a while – why do we need 4 kinds of mocks anyway?

All differences boil down to one thing – how the mock handles unrecorded calls:

  • StrictMock (_repo.CreateMock overloads), any unexpected call results in exception being thrown.
  • DynamicMock (_repo.DynamicMock overloads), any unexpected call returns default(T), where T is return type, that is null or 0 for value types.
  • PartialMock (_repo.PartialMock overloads), this works only for classes and any unexpected call is not intercepted but forwarded to the actual method of that class.
  • Stub (_repo.Stub), this is similar to DynamicMock with addition, that if you assign a value to a property, it remembers that value.

Those are all very important differences but I’d say quite subtle. Subtle to a point, that I am willing to agree that specifying them upfront either via explicitly named creation method, or via explicit parameter is throwing “in your face!” decisions that you shouldn’t have to be concerned about at this point.

Morten Lyhr noticed this as well, and he suggested the following solution:

public class LoginPresenterFixture
{
   private MockRepository _mockRepository;
   private LoginPresenter _loginPresenter;
   private LoginView _loginView;
   [SetUp]
   public void Init()
   {
      _mockRepository = new MockRepository();
      _loginView = _mockRepository.DynamicMock<LoginView>();
      CreateLoginPresenter();
   }
   private void CreateLoginPresenter()
   {
      _loginPresenter = new LoginPresenter(_loginView);
   }
   [Test]
   public void Strict_Test_Not_As_Often_Used()
   {
      //Override default mock kind
      _mockRepository.StrictMockBehaviour(_loginView);//this is important
      using (_mockRepository.Record())
      {
         Expect.Call(_loginView.ShowView);
      }
      using (_mockRepository.Playback())
      {
         _loginPresenter.Show();
      }
   }
}

It’s some way of dealing with it but it still requires you to explicitly assign behavior to mock object.

It’s still incorrect level of granularity though: instead of class level (different class per different mock kind) we now deal with it on object level (different kind per object).

I’d however move it yet one step further, to method level (different kind per method).

It might look something like this:

   [Test]
   public void Strict_Test_Not_As_Often_Used()
   {
      using (_mockRepository.Record())
      {
         Expect.Call(_loginView.ShowView);
         //Decide what to do with unexpected calls:
         Expect.For(_loginView).NothingElse();//this is important
      }
      using (_mockRepository.Playback())
      {
         _loginPresenter.Show();
      }
   }

Again, difference is very subtle, but important: instead of explicitly deciding about kind of mock, we decide about what to do about unexpected calls, which is more natural and closer to the actual problem. Different kinds of mocks, are just proposed solutions. The ‘kind’ is no longer a property of the mock object.

It also makes it easier to start with mocking framework: decision about what to do about unexpected calls is not thrown at your face at the very first lines, hidden behind terms like “Partial” or “Dynamic”. Instead you make that decision explicitly (and this time it’s a good thing) in last responsible moment that is in the actual test.

Technorati Tags: , , ,