Day 4 – Dot NET On Linux – Mocking with Rhino Mocks

Intro

“Rhino Mocks is a dynamic mock object framework for the .Net platform. Its purpose is to ease testing by allowing the developer to create mock implementations of custom objects and verify the interactions using unit testing.”

The Source Code

This post is part of my Dot Net On Linux posts. All the source the source code is available on GitHub here

What is a ‘Mocking’ framework?

Mocking allows us to fake the components in our system which can not be unit tested. This might be because the resource is expensive to unit test such as a database or is outside of our domain such as a web service. By mocking these objects and faking any actions required by them including returning fake responses or data, we can increase the coverage of our unit tests.

How To Mock

Though strictly not necessary it is recommend for code to adhere to the Interface Segregation Principle. We can then mock our interface and use DI to inject our mock into our interface. See my previous blog for using the Ninject dependency injection framework.

The mock framework will absorb any calls to the class or interface that it is mocking. If we need to return data, respond to requests or throw exceptions we can stub the mock to simulate this.

We are going to be using the mocking framework Rhino Mocks. It’s usage has simplified since version 3.5. The traditional record and playback syntax has been replaced by a simpler syntax like Moq though still allows us to Stub and Moq. There is a difference between mocking and stubbing and I would recommend reading the following post.

Download

I won’t lie here. I am a little bit confused. 3.5 is stable though I can only find the download for 3.6 which is a nightly build. Seeing as we are only investigating I don’t see any problem using a development build.

Downloads can be found here or here.

Install

Unzip and place somewhere useful. Installation into our solution is as simple as adding a reference to the Rhino.Mocks.dll which should be extracted.

Simply add a reference to the Rhino.Mocks.dll in your unit test project. Project –> Edit References to activate the Edit References dialog. Navigate to the unzipped directory and select Rhino.Mocks.dll.

Lets Code

We are going to mimic a Domain Driven Design strategy which might be similar to some code we would like to unit test but can’t without a database with read and write access.  Please note this is only a crude mimic to show the principle only and not a true DDD design strategy. We want to save a Model class via a Model Repository. Though we only have one model in our domain we will use an aggregate called Model Creator.. Again not strictly DDD but a close enough representation to show how we can effectively mock our DAL for unit testing. In this case our DAL is our Model Repository which implements IModelRepository.

Below is the code required to initiate our mock including creating a mock, stubbing any functions or properties we would like to fake and binding our mock to our interface within our DI kernel.

using Rhino.Mocks;
using Rhino;

[TestFixtureSetUp]
public void PreTestInitialize ()
{

	// instance variable which stores or fake database data.
	mockedModels = new List () {
		new Model() { FieldA = 1, FieldB = "Mock 1"},
    	new Model() { FieldA = 2, FieldB = "Mock 2"},
    	new Model() { FieldA = 3, FieldB = "Mock 3"},
    	new Model() { FieldA = 4, FieldB = "Mock 4"}
	};

	// we mock our IModelRepository with RhinoMocks
	IModelRepository mock = MockRepository.GenerateStub ();

	// We stub the database read function GetModels on IModelReposiotry

	mock.Stub (m => m.GetModels ()).Return (mockedModels);

	// We stub a properry to prove that our reale ModelRepository (set to false) is not being used.
	mock.Stub (m => m.IsMock).Return (true);

	// we use out Ninject DI framework to inject our mock repository
	ninjectKernel.Bind ().ToConstant (mock);
}

We can then fake the GetModels function by creating a mock object to fake a response and inject a concrete class to our abstraction via our DI kernel. The models are retrieved as expected and without touching our database.


[Test()]
public void CanMockMethodTest ()
{
	var modelCreator = ninjectKernel.Get ();

	var models = modelCreator.GetModels ();

	Assert.AreEqual (models.FirstOrDefault ().FieldA, mockedModels.First ().FieldA);
	Assert.AreEqual (models.FirstOrDefault ().FieldB, mockedModels.First ().FieldB);
}

The mock absorbs all public entities upon the object we are mocking. Our aggregate calls add upon our repository when we call CreateModel even thought it does not return any data. We did not mock this call but we still would like to assure that the Add function was called. We can test this by asking it!.


[Test()]
<pre>public void CanMockCreate ()
{
	var modelCreator = ninjectKernel.Get ();
	var modelRepository = ninjectKernel.Get ();

	var aModel = new Model () { FieldA = 1, FieldB = "Test"};
	modelCreator.CreateModel (aModel);

	modelRepository.AssertWasCalled (p => p.Add (aModel));
}

Our ModelRepository has a property is IsMock which is hard coded to false. We stubbed the property to be true within our mock repository. Some added prof that out concrete ModelRepository is not called upon for our mock testing.

[Test()]
public void CanMockProperty ()
{
	var modelCreator = ninjectKernel.Get ();

	Assert.IsTrue( modelCreator.IsMock);
}
Advertisements

Leave a Reply

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