Rhino MockRepository Concrete vs Static Usage

In this article we'll see the difference between usage of a MockRepository object initialization vs using Static functions to create and set up the mock/stubs. In the initial version of Rhino mocks it was the object that was being used but once the DynamicMock and Strick mocks become popular, a new static function was being introduced in it's release 3.5.

Readers Note: I'm expecting that if you're reading this article then you're already familiar with Unit Testing and the requirements of Mock objects with the basics of Rhino mocks.

Using the MockRepository concrete:

When we use the repository object to create and setup the expectations like:

var mocks = new MockRepository();

In this case when we start creating and setting up the expectations, the object automatically goes into the Record mode and it won't change its state until you call PlayBack() or RelayAll() on the repository object. So to use the concrete object of the repository usie it as in the following:

public void When_user_forgot_password_should_save_user()
{
    var mocks =
new MockRepository();
    var mockUserRepository = mocks.DynamicMock<IUserRepository>();
    var stubbedSmsSender = mocks.GenerateStub<ISmsSender>();
    using(mocks.Record())
    {
        var theUser = new User{HashedPassword = "this is not hashed password"};     
        mockUserRepository.Stub(x => x.GetUserByName("cshandler")).Return(theUser);
        mockUserRepository.Expect( x => x.Save(theUser) );
    }
    using(mocks.Playback())
    {
        var controllerUnderTest = new LoginController(mockUserRepository, stubbedSmsSender);
        controllerUnderTest.ForgotMyPassword("cshandler");
    }
}

Here we will see the Record block and Playback block are seperated out to keep the repository object separate from the default behavior.

Now if you don't want to use these blocks then the Static functions of the MockRepository class will be your friend. Let's have a look at the following snippet:

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(
"cshandler")).Return(theUser);
    mockUserRepository.Expect( x => x.Save(theUser) );
    var controllerUnderTest =
new LoginController(mockUserRepository, stubbedSmsSender);
    controllerUnderTest.ForgotMyPassword(
"cshandler");
    mockUserRepository.VerifyAllExpectations();
}

This is quite easy to write and easily readable. Though there are differences between the usages.

If you are using the Instance then you don't need to call the VerfiyAllExpectations() method while in the case of without using the instance it is required to call this function explicitly. These two ways of using the mock/stub with Rhino mocks are standard. So be careful when you're choosing any approach. Do not mix both methodologies or you'll end up getting unexpected errors. I'm sharing a small checklist that might help you when you start working with Rhino mocks.

Tips to remember while using Rhino mocks:

  1. Stub() defines the behavior for stubbed object.
  2. Expect() defines the behavior and the expectation for mocked object.
  3. Follow the principle of "Test only one thing per test".
  4. A mockrepositoryObject doesn't stop recording until you call ReplayAll.

    Try using repositoryInstance.PlayBack();

    Code:

    using (repository.Playback())
     {
     }

    Call repository.VerfiyAll() in the end.
     

  5. Use strickMock for defined behavior and strict expectation for method and properties call.
  6. Use DynamicMock for object behavior testing for a data supplied.

    More on Stub() and Mock(): A mock is an object that we can set expectations on, and that will verify that the expected actions have indeed occurred. A stub is an object that you use to pass to the code under test. You can set up expectations on it, so it would act in certain ways, but those expectations will never be verified.

    A stub's properties will automatically behave like normal properties, and you can't set expectations on them. If you want to verify the behavior of the code under test, you will use a mock with the appropriate expectation, and verify that. If you want just to pass a value that may need to act in a certain way, but isn't the focus of this test, you will use a stub.

    IMPORTANT: A stub will never cause a test to fail. (See release notes 3.5 of Rhino mocks.)
     
  7. Use the following statement for debugging and detailed logging:

    RhinoMocks.Logger = new TextWriterExpectationLogger(Console.Out);
     


Similar Articles