Optimise Rhino.Mocks tests using a base class
27 04 2008It’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”); } }
Comments : No Comments »
Tags : mbunit, nbehave, rhino.mocks
Categories : Uncategorized