Getting Started with Rhino Mocks (AAA)

When you’re writing unit tests for your code, you want to write specific tests for specific units. Unfortunately, it is not uncommon for you code to have many external dependencies that may not be related to the functionality that you’re trying to test. This is where one of my very favorite unit testing tools, Rhino Mocks, comes into play.

Rhino Mocks is great because it allows you to mock or stub objects in your code so that you can really focus on the functionality that you’re trying to test without having to worry about doing an excessive amount of setup or external dependencies.

When you’re getting started with Rhino Mocks, one of the most confusing things that you’ll run into is that there are several different syntaxes that can be used to accomplish the same thing. The AAA (Arrange, Act, Assert) syntax is the newest and was introduced with version 3.5. The primary distinction of the AAA syntax is that you don’t need to create and manage a MockRepository object and its various states.

In this article, I will walk you through the task of writing a unit test using Rhino Mocks.

So, before we begin writing our tests, let’s look at the code we’ll be testing.

public class Controller
{
    public IDataSource DataSource { get; set; }

    public int[] Data { get; set; }

    public void Process()
    {
        if (this.DataSource.DataAvailable())
        {
            this.Data = this.DataSource.GetData();
        }
    }
}

We can see that we have a Controller class that utilizes some sort of IDataSource object to check for and retrieve data. When we’re testing our controller class, we may or may not have access to our data source, though. And, even if we do have access to the data source, we may not have complete control over it. So this is an excellent situation to employ Rhino Mocks!

The first step to using Rhino Mocks is simply adding a reference to your project. Once the reference is in place, we can add the using statement to the top of our test class and get to mockin’.

Creating a mock object is extremely simple with Rhino Mocks’s AAA syntax. You just use the static MockRepository class’s GenerateMock function.

var mockDataSource = MockRepository.GenerateMock();

Now that we’ve created our mock object, we need to configure our target object to use it. In this case, our class’s IDataSource is a public property on the class. So configuring the target object is a simple assignment.

Controller target = new Controller();
target.DataSource = mockDataSource;

Okay, great! Our next step is to set the expectations for our mock object. For our first test, we’ll just have the call to DataAvailable return false.

mockDataSource.Expect(x => x.DataAvailable()).Return(false);

The last steps for this test are to run the function we’re testing and verify that our mock object was used as expected.

target.Process();
mockDataSource.VerifyAllExpectations();

When we run this test, the Process function will call our mock object’s DataAvailable function–which we have pre-configured to return false–and the test will pass as long as DataAvailable is called.

We can run this test, and it should pass. Awesome, now let’s write another test. This time, we’ll have DataAvailable return true. We create the mock object the same way as previously, but we’ll need to set the expectations differently.

mockDataSource.Expect(x => x.DataAvailable()).Return(true);
var data = new int[] {1, 2, 3};
mockDataSource.Expect(x => x.GetData()).Return(data);

Since we’re passing some data in, we can also add an extra assertion in our unit test.

mockDataSource.VerifyAllExpectations();
Assert.AreEqual(data, target.Data);

This unit test will fail unless both DataAvailable and GetData are called. Additionally, the target object’s Data property must be the object returned by GetData.

Here is the complete text for the two unit tests we’ve just created.

[TestMethod()]
public void ProcessTest_DataAvailableReturnsFalse()
{
    var mockDataSource = MockRepository.GenerateMock();

    Controller target = new Controller();
    target.DataSource = mockDataSource;

    mockDataSource.Expect(x => x.DataAvailable()).Return(false);

    target.Process();
    mockDataSource.VerifyAllExpectations();
}

[TestMethod()]
public void ProcessTest_DataAvailableReturnsTrue()
{
    var mockDataSource = MockRepository.GenerateMock();

    Controller target = new Controller();
    target.DataSource = mockDataSource;

    mockDataSource.Expect(x => x.DataAvailable()).Return(true);
    var data = new int[] { 1, 2, 3 };
    mockDataSource.Expect(x => x.GetData()).Return(data);

    target.Process();
    mockDataSource.VerifyAllExpectations();
    Assert.AreEqual(data, target.Data);
}
Advertisements

5 thoughts on “Getting Started with Rhino Mocks (AAA)”

  1. The following post, “Getting Started with Rhino
    Mocks (AAA) | adamprescott.net” displays that u actually fully understand everything that you r communicating
    about! I personally completely agree with your post.

    Thank you -Alethea

  2. HI Adam,

    Please provide me something to get started with Rhino Mocks concept. After going through this post, I get a feel of what Rhino Mocks can do but I would request you to provide something more basic assuming you audience are first time users of this framework.

    Any links for documentations with examples and videos would help.

    Highly appreciate your efforts !!

    Thanks,
    Dinesh

    1. hi mr adam

      thank you for your post

      i concur with mr dinesh above.

      i clicked on the link but could not find how to get rhino mocks. do i have to download and install anything or do I just need to add a class library to my project? is it possible to get it with nuget?

      rgds

      Ben

  3. Hey Adam, it’s George (from New World). Just wanted you to know that Tyler Tech has this blog linked in their confluence page!

    Your name lives on! Hope you’re doing well 🙂

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s