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”);
}
}