Some days ago I discovered a nice Quick Reference document for Rhino Mocks 3.3
This document can be very usefull to understand the syntax of this great mocking framework.
May 3, 2008
Rhino Mocks 3.3 Quick Reference
April 27, 2008
Optimise Rhino.Mocks tests using a base class
It’s usual my team to use ModelViewPresenter pattern and than use Rhino.Mocks to test Presenter without concrete View and Model. Rhino.Mock is a great tool but its usage can be quite booring as it requires some repeated code for each test. Here a sample:
public class Presenter { public Presenter(IView view, IModel model) { model.Loaded += delegate { throw new NotImplementedException(); }; } } public interface IModel { event EventHandler Loaded; } public interface IView { }
I want to test that during constructor Presenter subscribe model Loaded event. So I need to write this unit test using Rhino.Mocks:
[TestFixture] public class ClassicMockingSample { private IView _view; private IModel _model; private MockRepository _repository; [SetUp] public void SetUp() { _repository = new MockRepository(); _view = _repository.Stub<IView>(); _model = _repository.CreateMock<IModel>(); } [Test] public void Ctor_Always_SubscribeModelEvents() { using (_repository.Record()) { Expect.Call(delegate { _model.Loaded += null; }) .Constraints(Is.NotNull()); } using (_repository.Playback()) { new Presenter(_view, _model); } } }
Looking at NBehave framework I discover a usefull class SpecBase that hides the codes needed to create MockRepository repository and give you more readable code.
Here the same test as shown before but refactored using SpecBase class
[Context] public class NBehaveLikeMockingSample : SpecBase { private IModel model; private IView view; protected override void Before_each_spec() { model = Mock<IModel>(); view = Stub<IView>(); } [Specification] public void Ctor_Always_SubscribeModelEvents() { using (RecordExpectedBehavior) { Expect.Call(delegate { model.Loaded += null; }) .Constraints(Is.NotNull()); } using (PlaybackBehavior) { new Presenter(view, model); } } }
As you can see there is nothing magic here.
It’ just a more readable unit test. Context and Specification attribute are alias of MbUnit attribute
using Context = MbUnit.Framework.TestFixtureAttribute; using Specification = MbUnit.Framework.TestAttribute;
As I don’t need all the NBehave framework for the moment I decided to copy the class SpecBase inside my UnitTest Assembly after removing the AutoMocking feature.The code it’s here:
public class SpecBase { private MockRepository _mocks; protected IDisposable RecordExpectedBehavior { get { return _mocks.Record(); } } protected IDisposable PlaybackBehavior { get { return _mocks.Playback(); } } [SetUp] public void MainSetup() { _mocks = new MockRepository(); Before_each_spec(); } [TearDown] public void MainTeardown() { After_each_spec(); } protected virtual void Before_each_spec() { } protected virtual void After_each_spec() { } protected TType Mock<TType>() { return _mocks.DynamicMock<TType>(); } protected TType Mock<TType>(object[] prams) { return _mocks.DynamicMock<TType>(prams); } protected TType Partial<TType>() where TType : class { return _mocks.PartialMock<TType>(); } protected TType Stub<TType>() { return _mocks.Stub<TType>(); } protected void Verify(object mock) { _mocks.Verify(mock); } protected void VerifyAll() { _mocks.VerifyAll(); } protected void Spec_not_implemented() { Assert.Ignore("Spec not implemented"); } }