HowTo – Rhino Mocks

Source Code

All source code can be found on GitHub here.

My cheat sheet in generics can be found here while some code examples in generics can be found in my post here.

This is part of my HowTo in .NET seriies. An overview can be seen here,

Intro

Rhino Mocks is a mocking framework for .Net. In essence a mocking framework allows you to stub a complex expensive resource such as a database or webserver. However mocking frameworks can allow you to completely isolate a SUT during testing. Mocking frameworks also allow the creation of expectations of methods calls between a mock and the SUT; the unit test will then fail if the expected method calls were not made or made but with the wrong parameter values. Testing can then be behavioural as well as state based. This how to looks at the syntax for version 3.6 and above which does not require the record and playback syntax.

Stubs

Stub A Method

The simplest explanation of when to stub is when a resource such as a database or web service is encountered; something which is expensive to consume when unit testing. Providing a stub for a class which consumes a database can allow us to substitute this at run time making unit testing quicker and easier but also it can allow us to very easily create complex unit tests with a wealth of data which is very easy to set up without having to create test data within a database. The following simple example mocks an interface called method called Do() on interface ISimpleModel which takes no parameters and when called returns 1 as an integer. MockRepository is used to create a fake or stubbed instance of ISimpleModel, it is upon this that we are required to call our functions. If we were stubbing a class and not an interface then one thing to note is that you would not get any functionality of the class. You can not mix and match functionality of the class and stubbed functions.

var sut = MockRepository.GenerateStub();
sut.Stub(x => x.Do()).Return(1);

Stub A Property

Get functions of properties can be stubbed. The following syntax allows stubbing of a readonly property (get only).

var sut = MockRepository.GenerateStub();
sut.Stub(x => x.AReadonlyPropery).Return(1);

The following syntax allows stubbing of a get method of a property.

var sut = MockRepository.GenerateStub();
sut.AProperty = 2;  // Stubs a Get_AProperty as 2
Assert.That(sut.AProperty.Equals(2));

It is not required to stub set methods. Any methods can be consumed automatically without stubbing them, only if we need a return value other than default(T) for value types and null for reference types do you need to stub the method. Set methods return void so stubbing this is not required.

Arguments

If our stubbed methods takes arguments then we need to provide for them.

Ignoring Arguments

In the simplest form we might not care what values the parameters take and can simply state that they can be anything. Allow the argument to be Anything.

sut.Stub(x => x.Do(Arg.Is.Anything)).Return(1);

Call IgnoreArguments() will make any constrained arguments parameters have their constraints ignored.

sut.Stub(x => x.Do(Arg.Is.Equal(1))).IgnoreArguments().Return(1);

Constrained Arguments

Constrained arguments allow us to return different data based upon the method parameter values which it is called upon. When all parameters are matched the return is made. If multiple stubs are matched then the first registered stub instance is used to determine the return value.

Is

Is constants provide predicates for literal and reference types. The following is a quick run through of the Is argument constraints. Equal and NotEqual for equality based comparison.

sut.Stub(x => x.Do(Arg.Is.Equal(1))).Return(1);
sut.Stub(x => x.Do(Arg.Is.NotEqual(1))).Return(10);

Comparison between two literals.

sut.Stub(x => x.Do(Arg.Is.GreaterThanOrEqual(10))).Return(1);
sut.Stub(x => x.Do(Arg.Is.GreaterThan(10))).Return(2);
sut.Stub(x => x.Do(Arg.Is.LessThanOrEqual(10))).Return(1);
sut.Stub(x => x.Do(Arg.Is.LessThan(10))).Return(2);

Comparison to null with Is.Null and Is.NotNull.

sut.Stub(x => x.DoIFoo(Arg.Is.Null)).Return(1);
sut.Stub(x => x.DoIFoo(Arg.Is.NotNull)).Return(2);

IsTypeOf to determine if the type is of the required type. In this example Moo and Foo both implement IFoo Whig is the parameter type. Based upon whether Foo or Moo is passed in we can alter our return value.

sut.Stub(x => x.DoIFoo(Arg.Is.TypeOf)).Return(1);
sut.Stub(x => x.DoIFoo(Arg.Is.TypeOf)).Return(2);

Identity comparison with Same and NotSame functions.

sut.Stub(x => x.DoIFoo(Arg.Is.Same(foo))).Return(1);
sut.Stub(x => x.DoIFoo(Arg.Is.NotSame(foo))).Return(2);

List

The List functions allow us to provide predicates upon elements which implement IEnumerable and IEnumerable. I aliased RIS as ‘using RIS = Rhino.Mocks.Constraints.Is;’ to make a distinction between NUnit and Rhino Mocks Is. The simplest form of List is the count which allows us to compare the element count against an Is constraint. Any of the Is constraints which predicate numbers can be used; Equal IsLessThan etc. Below we stub Do(IList t) twice once for when the parameter contains no elements and another for one element.

sut.Stub(x => x.Do(Arg>.List.Count(RIS.Equal(0)))).Return(0);
sut.Stub(x => x.Do(Arg>.List.Count(RIS.Equal(1)))).Return(1);

Element allows comparison of element at a position to an Is constraint. The first parameter is the element position and the second parameter is an Is constraint.

sut.Stub(x => x.Do(Arg>.List.Element(0, RIS.Equal(1)))).Return(1);
sut.Stub(x => x.Do(Arg>.List.Element(1, RIS.GreaterThanOrEqual(2)))).Return(2);

Equal allows comparison of a collection to another.

sut.Stub(x => x.Do(Arg>.List.Equal(new int[] { 1, 2, 3 }))).Return(1);
sut.Stub(x => x.Do(Arg>.List.Equal(new int[] { 4, 5, 6 }))).Return(2);

IsIn allow predicating if an element is contained within the collection.

sut.Stub(x => x.Do(Arg>.List.IsIn(1))).Return(1);
sut.Stub(x => x.Do(Arg>.List.IsIn(4))).Return(2);

OneOf allows predicate for any elements in both collections;

if one or more elements are found in both collections then the predicate is deemed as passed.

sut.Stub(x => x.Do(Arg.List.OneOf(new int[] { 1, 2, 3 }))).Return(1);
sut.Stub(x => x.Do(Arg.List.OneOf(new int[] { 4, 5, 6 }))).Return(2);

Matches

When the predicate is more complex or the built in functionality is not sufficient the Matches function provides more scope by taking a Predicate delegate; if you can write it you can predicate it!

sut.Stub(x => x.Do(Arg.Matches(y => y > 5))).Return(1);

Repeat

It is possible to set up the stubbing for x number of repetition; thus we can return different results dependant upon the call iteration. The methods Once(), Twice() and Times(int x) are provided.

mock = MockRepository.GenerateStub();
mock.Stub(x => x.Do()).Return(1).Repeat.Once();
mock.Stub(x => x.Do()).Return(2).Repeat.Twice();
mock.Stub(x => x.Do()).Return(3).Repeat.Times(3);

ByRef and Out Parameters

By Ref parameters can be implemented by utilising the ref keyword along with the Ref and Dummy methods.

sut.Stub(x => x.Do(Arg.Is.Equal(1), ref Arg.Ref(RIS.Equal(0), 10).Dummy)).Return(1);

Out parameters can be implemented by utilising the out keyword along with the Out and Dummy methods.

sut.Stub(x => x.Do(Arg.Is.Equal(1), Arg.Is.Equal("Hello"), out Arg.Out(10).Dummy)).Return(1);

By Literal

Though highly discouraged stubbing by literals can also be utilised.

sut.Stub(x => x.Do(1).Return(1);
sut.Stub(x => x.Do("Foo").Return(2);

Mocks

A Mock is similar to a Stub, in fact it contains all the functionality mentioned above however mocks can record required behaviour and fail a unit test if the required behaviour is not called upon by the SUT. For example If we have a class A which requires to call two methods on class B with certain parameters we can ensure that all of this behaviour is called or fail the unit test. We can either place expectation calls on the mock prior to the unit test act or we can make assertions of function calls during the assert.

Assert Was Called

AssertWasCalled provides a way asserting that a function call with required parameters was called. If a return value is required then this method can not be used.

Argument Constraints

All argument constraints mentioned previously in the stubs section can and should be utilised along with the AssertWasCalled function. If the function was not called with the parameter constraints then an exception is thrown and as such the unit test fails. The following example shows how to ensure that a function is called ignoring the parameter values.

[Test]
public void WhenArgumentsIsAnything()
{
	IModelRepository mock = MockRepository.GenerateMock();

 	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	modelCreator.CreateModel(theModel);

 	mock.AssertWasCalled(p => p.Add(Arg.Is.Anything));
 }

The following example shows how to ensure that a function is called ensuring that the parameter is not null.


[Test]
public void WhenArgumentsIsNotNull()
{
	IModelRepository mock = MockRepository.GenerateMock();

 	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	modelCreator.CreateModel(theModel);

 	mock.AssertWasCalled(p => p.Add(Arg.Is.NotNull));

 }

The following example shows how to ensure that a function is called ensuring that the parameter is equal to a reference type.

[Test]
public void WhenArgumentsIsEqual()
{
	IModelRepository mock = MockRepository.GenerateMock();

 	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	modelCreator.CreateModel(theModel);

 	mock.AssertWasCalled(p => p.Add(Arg.Is.Equal(theModel)));

 }

Assert Was Not Called

AssertWasNotCalled works exactly the same as AssertWasCalled however it throws an exception and fails the unit test if the method with argument constraints was called.

[Test]
public void WhenNotCalled()
{
	IModelRepository mock = MockRepository.GenerateMock();

 	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	modelCreator.CreateModel(theModel);

 	mock.AssertWasNotCalled(p => p.Add(Arg.Is.Null));

}

Properties

The syntax for asserting that a readonly property or get method of a property is exactly the same as each other (unlike when we look at Expect and Verify!).


[Test] public void WhenReadonlyProperty()
{
	var sut = MockRepository.GenerateMock();

 	var foo = sut.AReadonlyPropery;

 	Assert.That(foo.Equals(0));

 	sut.AssertWasCalled(x => x.AReadonlyPropery);

 }

 

[Test]
public void WhenProperyGetCalled()
{
	var sut = MockRepository.GenerateMock();

 	Assert.That(sut.AProperty, Is.EqualTo(0));

 	sut.AssertWasCalled(x => x.AProperty);

 }

Asserting that a set method of a property is called with a literal value.

[Test]
public void WhenProperySetCalled()
{
	var sut = MockRepository.GenerateMock();

 	sut.AProperty = 9;

 	Assert.That(sut.AProperty, Is.EqualTo(0));

 	sut.AssertWasCalled(x => x.AProperty = 9);

 }

Expect and Verify

Expect and Verify has two advantages over the AssertWasCalled style syntax. Firstly it allows stubbing inline with the Expect function call and secondly it allows setting the expectations as part of the assign stage along with other Stub functionality which might be required. The Expect() method allows all argument constraints as shown in the stub section above and works exactly the same as stub however if when VerifyAllExpectations is called as part of the assert section of the unit test any configured expects which have not been called or called with the required parameters, an exception is thrown and the unit test fails. Unlike AssertWasCalled syntax no equivalent functionality for AssertWasNotCalled is provided.

Argument Constraints

All argument constraints are available. Below are a few examples The following example shows how to ensure that a function when it does not matter what parameters are used.

[Test]
public void WhenArgumentIsAnything()
{
	IModelRepository mock = MockRepository.GenerateMock();

	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	mock.Expect(p => p.Add(Arg.Is.Anything));

 	modelCreator.CreateModel(theModel);

 	mock.VerifyAllExpectations();

 }

The following example shows how to ensure that a function only requires that the function is called without a reference type being null.

[Test]
public void WhenArgumentIsNotNull()
{
	IModelRepository mock = MockRepository.GenerateMock();

 	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	mock.Expect(p => p.Add(Arg.Is.NotNull));

 	modelCreator.CreateModel(theModel);

 	mock.VerifyAllExpectations();

 }

The following example shows how to ensure that a function with equality check for a reference type.

[Test] public void WhenArgumentIsEqualTo()
{
	IModelRepository mock = MockRepository.GenerateMock();

 	var modelCreator = new ModelCreator(mock);

 	var theModel = new AnotherModel() { FieldA = 1, FieldB = "Test" };

 	mock.Expect(p => p.Add(Arg.Is.Equal(theModel)));

 	modelCreator.CreateModel(theModel);

 	mock.VerifyAllExpectations();

 }

The following example shows how to ensure that a function is called with a number type parameter equal to 9.

[Test]
public void WhenReadonlyPropertyCalled()
{
	var sut = MockRepository.GenerateMock();

	sut.Expect(x => x.AReadonlyPropery).Return(9);

 	Assert.That(sut.AReadonlyPropery, Is.EqualTo(9));

 	sut.VerifyAllExpectations();
}

Properties

The first example shows how to place an expectation on a get method of a property.

[Test]
public void WhenPropertyGetCalled()
{
	var sut = MockRepository.GenerateMock();

 	sut.Expect(x => x.AProperty).Return(9);

 	Assert.That(sut.AProperty, Is.EqualTo(9));

 	sut.VerifyAllExpectations();

 }

This example shows how to place an expectation on a set method while ignoring the parameter value.

[Test]
public void WhenPropertySetCalledWithIgnoreArguments()
{
	var sut = MockRepository.GenerateMock();

 	sut.Expect(x => x.AProperty).SetPropertyAndIgnoreArgument();

 	sut.AProperty = 1;

 	sut.VerifyAllExpectations();

 }

This example shows how to place an expectation on a set method with an explicit value.

[Test]
public void WhenPropertySetCalledWithArguments()
{
	var sut = MockRepository.GenerateMock();

 	sut.Expect(x => x.AProperty).SetPropertyWithArgument(11);

 	sut.AProperty = 11;

 	sut.VerifyAllExpectations();
 }
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