Rhino Mocks 3.5 Design DecisionsThe role of Stub vs. Mock

time to read 2 min | 235 words

Let us say that we have the following code that we want to test:

public void ForgotMyPassword(string username)
{
   var user = users.GetUserByName(username);
   user.HashedPassword = "new pass";
   users.Save(user);
}

One way to write the test is:

public void When_user_forgot_password_should_save_user()
{
    var mockUserRepository = MockRepository.GenerateMock<IUserRepository>();
    var stubbedSmsSender = MockRepository.GenerateStub<ISmsSender>();

    var theUser = new User{HashedPassword = "this is not hashed password"};    

    mockUserRepository.Stub(x => x.GetUserByName("ayende")).Return(theUser);

    mockUserRepository.Expect( x => x.Save(theUser) );

    var controllerUnderTest = new LoginController(mockUserRepository, stubbedSmsSender);

    controllerUnderTest.ForgotMyPassword("ayende");

    mockUserRepository.VerifyAllExpectations();
}

Another would be:

public void When_user_forgot_password_should_reset_password()
{
    var stubUserRepository = MockRepository.GenerateStub<IUserRepository>();
    var stubbedSmsSender = MockRepository.GenerateStub<ISmsSender>();

    var theUser = new User{HashedPassword = "this is not hashed password"};    

    stubUserRepository.Stub(x => x.GetUserByName("ayende")).Return(theUser);

    var controllerUnderTest = new LoginController(mockUserRepository, stubbedSmsSender);

    controllerUnderTest.ForgotMyPassword("ayende");

    stubUserRepository.AssertWasCalled( x => x.Save(user));
}

Again, we have the question of should we even allow asserts on stubs. But beyond that, consider this two tests, both are functionally the same. Thoughts?

More posts in "Rhino Mocks 3.5 Design Decisions" series:

  1. (30 Jun 2008) Getting closer to conclusion
  2. (29 Jun 2008) The role of Stub vs. Mock
  3. (29 Jun 2008) To be strict or not?