Total Pageviews

Friday, October 12, 2012

Rhino Mock Testing


http://ayende.com/wiki/Rhino+Mocks+Documentation.ashx?AspxAutoDetectCookieSupport=1

Rhino Mocks allows you to easily create mock objects and setup a wide range of expectations on them using strongly typed notation instead of compiler-opaque strings. It's as simple as:
IProjectView projectView = mocks.StrictMock<IProjectView>();
Expect.Call(projectView.Title).Return("Project's Title");
Definitions:

  • Mock Object - an object that pretends to be another object and allows you to set expectations on its interactions with another object.
  • Interaction Based Testing - you specify a certain sequence of interactions between objects, initiate an action, and then verify that the sequence of interactions happened as you specified it.
  • State Based Testing - you initiate an action and then check for the expected results (return value, property, created object, etc).
  • Expectation - general name for validation that a particular method call is the expected one.
  • Record & Replay model - a model that allows for recording actions on a mock object and then replaying and verifying them. All mocking frameworks uses this model. Some (NMock, TypeMock.Net, NMock2) use it implicitly and some (EasyMock.Net, Rhino Mocks) use it explicitly.
  • Ordering - The ability to specify that replaying a sequence of method calls will occur in a specific order (or disorder).

Capabilities



  • mock interfaces, delegates and classes, including those with parameterized constructors.
  • set expectations on the called methods by using strongly typed mocks instead of strings.
  • lends itself easily to refactoring & leaning on the compiler.
  • allows a wide range of expectations to be set on a mock object or several mock objects.
  • Attention: Rhino Mocks can only mock interfaces, delegates and virtual methods of classes! (Although it is possible to get work around existing code and easily apply Rhino Mocks, see Example of testing an abstract class)


The purpose of mock objects is to allow you to test the interactions between components, this is very useful when you test code that doesn't lend itself easily to state based testing.
[Test]
public void SaveProjectAs_CanBeCanceled()
{
  MockRepository mocks = new MockRepository();
  IProjectView projectView = mocks.StrictMock<IProjectView>();
  Project prj = new Project("Example Project");
  IProjectPresenter presenter = new ProjectPresenter(prj,projectView);
  Expect.Call(projectView.Title).Return(prj.Name);
  Expect.Call(projectView.Ask(question,answer)).Return(null);
  mocks.ReplayAll();
  Assert.IsFalse(presenter.SaveProjectAs());          
  mocks.VerifyAll();
}
 
We create a MockRepository, a mock project view, project and a project 
presenter. Then we set the expectations. After we finished with setting 
up the expectations, we move to the replay state, and call the 
SaveProjectAs() method. It should return false if the user canceled the 
save process.

This example clarifies several key concepts related to Rhino Mocks.
  • We set expectation on object using the object's methods, and not strings. This reduces the chances of making a mistake that will only (hopefully) be caught at runtime - When tests are run.
  • We use explicit calls to move from Record state to Replay state.
  • We verify that all the expectations have been met.
 

No comments:

Post a Comment