Rhino Mocks
Rhino Mocks is an open source .NET mocking framework created by Oren Eini. Rhino Mocks source code is hosted at GitHub
Rhino Mocks Fundamentals
Install Rhino Mocks
Grab it from Rhino Mocks website or via NuGet:
PM> Install-Package RhinoMocks
Mocks in Rhino Mocks
You can easily create mocks in Rhino Mocks by using a MockingRepository as illustrated below:
var emailServiceMock = MockRepository.GenerateMock<IEmailService>();
And assert expectations like:
var emailServiceMock = MockRepository.GenerateMock<IEmailService>();
// Assert that a method was called
emailServiceMock.AssertWasCalled(e => e.sendReminder(user));
// Assert that a property was set
emailServiceMock.AssertWasCalled(e => e.StmpPort = 25);
Stubs in Rhino Mocks
Rhino Mocks also provides support for creating stubs:
var userRepositoryStub = MockRepository.GenerateStub<IUserRepository>();
And to configure them as detailed below:
var userRepositoryStub = MockRepository.GenerateStub<IUserRepository>();
// stub a method call
userRepository.Stub(r => r.GetUserById(user.Id)).Return(user);
userRepository.Stub(r => r.GetUser(Arg<User>.Is.Anything)).Return(user);
userRepository.Stub(r => r.UserExists(user)).Return(false);
// specifying property values
userRepository.Count = 0; // only works if property is not read only
userRepository.Stub(r => r.Count).Return(0); // for read-only properties
As a side note, you can also use GenerateMock
and use the generated object as a stub. (At the end of the day, a fake object becomes a stub or a mock depending on the way you use it in a test).
A Note About Rhino Mocks Constraints
Rhino Mocks Constraints give you a lot of flexibility in your test setups and assertions by providing a way to:
- setup method arguments to match a criteria
- verify that method arguments match a criteria
For instance:
// Arg<User>.Is.Anything is a constraint
mockUserRepository.AssertWasCalled(x => x.Save(Arg<User>.Is.Anything));
mockUserRepository.AssertWasCalled(x => x.Save(Arg<User>.Is.NotNull));
mockUserRepository.AssertWasCalled(x => x.Save(Arg<User>.))
It comes in any of these flavors: Is
, Matches
, List
and Text
.
The Is Constraint
Is
allows you to set up simple and common constraints.
Arg<T>.Is.Anything() // matches anything
Arg<T>.Is.Equal(something) // matches by equality
Arg<T>.Is.Null() // matches if null
Arg<T>.Is.NotNull() // matches if not null
Arg<T>.Is.Same(something)
Arg<T>.Is.NotSame(something)
Arg<T>.Is.GreatherThan(10)
Arg<T>.Is.LessThan(10)
The Matches Constraint
Matches
allows you to use a arbitrary predicates to set a constraint:
Arg<User>.Matches(u => u.Id == user.id) // match by user id
Arg<User>.Matches(u => u.FirstName == firstName && u.LastName == lastName) // match by user firstName and lastName
The List Constraint
List
allows you to set up constraints based on collections.
Arg<List<User>>.List.ContainsAll(students)
Arg<List<User>>.List.Equal(students)
Arg<List<User>>.List.Count(Rhino.Mocks.Constraints.Is.Equal(3))
Arg<List<User>>.List.IsIn(aStudent)
The Text Constraint
Text
allows you to set up constraints based on string matchings.
Arg<string>.Matches(Rhino.Mocks.Constraints.Text.Contains("hello"))
Arg<string>.Matches(Rhino.Mocks.Constraints.Text.StartsWith("hello"))
Arg<string>.Matches(Rhino.Mocks.Constraints.Text.EndsWith("world"))
Arg<string>.Matches(Rhino.Mocks.Constraints.Text.Like("hello.*")) // use regex
Constraints for Out and Ref Parameters
// Out parameters
userRepository.Stub(r => r.Get(out Arg<User>.Out(new User()).Dummy))
// Ref parameters
userRepository.Stub(r => r.Save(ref Arg<User>.Ref(constraint: Rhino.Mocks.Constraints.Is.Anything(), returnValue: new User())))
Creating Custom Constraints
Creating custom constraints in Rhino Mocks is as easy as creating a new implementation of AbstractConstraint
, the abstract base class for all constraints in Rhino Mocks.
// Constraint implementation
public class UserConstraint : AbstractConstraint
{
public UserConstraint(User expectedUser){...}
// The Eval method is called when the constraint is evaluated
public override bool Eval(object actual){...}
// The Message property returns a message
// to display when the constraint evaluates to false
public override string Message {get {...}}
...
}
...
// Constraint use
Arg<User>.Matches(new UserConstraint(expectedUser));
Resources
Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.