我正在进行一个项目,其中我们使用了 MVP 和 Rhino Mocks。我们所做的就是在每个测试中简单地期望所有事件订阅。
private void SetupDefaultExpectations()
{
_mockView.Initializing += null; LastCall.IgnoreArguments();
_mockView.SavingChanges += null; LastCall.IgnoreArguments();
}
然后我们在IMockedObject上(来自RhinoMocks)构建了一个扩展方法,在单元测试中触发事件并解开异常,以便可以按照标准的NUnit方式进行期望。
static class IMockedObjectExtension
{
public static void RaiseEvent(this IMockedObject mockView, string eventName, EventArgs args)
{
EventRaiser eventraiser = new EventRaiser(mockView, eventName);
try
{
eventraiser.Raise(mockView, args);
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
}
public static void RaiseEvent(this IMockedObject mockView, string eventName)
{
RaiseEvent(mockView, eventName, EventArgs.Empty);
}
}
这可以从单元测试中使用,像这样。
using(_mocks.Record())
{
Expect.Call(dependency.GetInfo()).Return(someList);
}
using(_mocks.Playback())
{
Presenter presenter = new Presenter(_mockView, dependency);
(_mockView as IMockedObject).RaiseEvent("SavingChanges");
}
为了消除演示者测试之间的重复,我们对其进行了重构,将其转换为 BasePresenterTest 基类,为所有演示者测试设置了这个基本结构,并向子类公开了辅助方法。
public abstract class BasePresenterTest<VIEW> where VIEW : IBaseView
{
protected MockRepository _mocks;
protected VIEW View { get; private set; }
protected abstract void SetUp();
protected abstract void TearDown();
protected abstract void SetupDefaultExpectations();
[SetUp]
public virtual void BaseSetUp()
{
_mocks = new MockRepository();
View = _mocks.CreateMock<VIEW>();
SetUp();
}
[TearDown]
public virtual void BaseTearDown()
{
TearDown();
View = null;
_mocks = null;
}
protected virtual void BaseSetupDefaultExpectations()
{
//Setup default expectations that are general for all views
SetupDefaultExpectations();
}
protected virtual IDisposable Record()
{
IDisposable mocksRecordState = _mocks.Record();
BaseSetupDefaultExpectations();
return mocksRecordState;
}
protected virtual IDisposable Playback()
{
return _mocks.Playback();
}
protected void RaiseEventOnView(string eventName)
{
(View as IMockedObject).RaiseEvent(eventName);
}
}
这能从我们项目的测试中删除许多代码。
我们仍在使用旧版本的RhinoMocks,但一旦我们转向较新版本,我将尝试更新它。