使用Moqvalidation事件注册

我正在开发一个尝试使用此示例实现MVP模式的asp.net(经典)应用程序。 在尝试对我的演示者进行unit testing并使用以下模式时,psuedocode看起来像这样

//base view interface public interface IView { event EventHandler Init; event EventHandler Load; bool IsPostBack { get; } void DataBind(); bool IsValid { get;} } //presenter psuedo code public class SomePresenter { public SomePresenter(ISomeDomainService service, IView someView) { ... //HOW DO WE TEST/VERIFY THAT THIS REGISTRATION OCCURS? someView.Init += OnInit; someView.Load += OnLoad; } } ... //consuming code that exercises the above code, that needs to be tested var presenter = new SomePresenter(someDomainService, someView); 

如何validation演示者是否正在执行预期的操作,即注册Init和Load事件? 虽然这很容易在Phil Haack使用Rhino 模拟的例子中完成…

 [Test] public void VerifyAttachesToViewEvents() { viewMock.Load += null; LastCall.IgnoreArguments(); viewMock.PostSaved += null; LastCall.IgnoreArguments(); mocks.ReplayAll(); new PostEditController(viewMock, this.dataServiceMock); mocks.VerifyAll(); } 

……我们怎么能用MOQ做到这一点?

看来这个function目前在moq中不可用 ,但可能会出现在未来的版本中(我看过4.0.812.4测试版,但它似乎并不存在)。

可能值得问一个问题,“为什么SomePresenter需要订阅View的LoadInit事件?” 大概是因为SomePresenter类需要响应这些事件。 因此,最好在Mock上使用Raise方法来引发LoadInit事件,然后声明SomePresenter在响应它们时做了正确的事情。

我知道#Dilip可能为时已晚,但这个答案对那些试图做同样事情的人有帮助。 这是测试类

 public delegate void SubscriptionHandler(string name, T handler); public class SomePresenterTest { [Test] public void Subscription_Test() { var someServiceMock = new Mock(); var viewMock = new Mock(); //Setup your viewMock here var someView = new FakeView(viewMock.Object); EventHandler initHandler = null; someView.Subscription += (n, h) => { if ((nameof(someView.Init)).Equals(n)) initHandler=h; }; Assert.IsNull(initHandler); var presenter = new SomePresenter(someServiceMock.Object, someView); Assert.IsNotNull(initHandler); Assert.AreEqual("OnInit", initHandler.Method?.Name); } } 

FakeView是一个实现如下的装饰器(注意事件:Init / Load {add; remove}):

 public class FakeView : IView { public event SubscriptionHandler Subscription; public event SubscriptionHandler Unsubscription; private IView _view; public FakeView(IView view) { Assert.IsNotNull(view); _view = view; } public bool IsPostBack => _view.IsPostBack; public bool IsValid => _view.IsValid; public event EventHandler Init { add { Subscription?.Invoke(nameof(Init), value); _view.Init += value; } remove { Unsubscription?.Invoke(nameof(Init), value); _view.Init -= value; } } public event EventHandler Load { add { Subscription?.Invoke(nameof(Load), value); _view.Init += value; } remove { Unsubscription?.Invoke(nameof(Load), value); _view.Init -= value; } } public void DataBind() { _view.DataBind(); } } 

我花了一些时间来处理这个问题,我在项目中使用的解决方案是:

unit testing:

 // Arrange TestedObject.Setup(x => x.OnEvent1()); TestedObject.Setup(x => x.OnEvent2()); // Act TestedObject.Object.SubscribeEvents(); TestedObject.Raise(x => x.Event1 += null); TestedObject.Raise(x => x.Event2 += null); // Assert TestedObject.Verify(x => x.OnEvent1(), Times.Once()); TestedObject.Verify(x => x.OnEvent2(), Times.Once()); 

测试方法:

 this.Event1 += OnEvent1; this.Event2 += OnEvent2; 

因此,在调用要测试的方法之后,首先必须模拟将分配事件的方法,最后提升所有已订阅的事件。 如果事件是真正订阅的,您可以检查Moq是否调用了指定的方法。

GLHF!