使用Moq验证事件注册

Dil*_*nan 23 .net c# asp.net unit-testing moq

我正在开发一个尝试使用此示例实现MVP模式的asp.net(经典)应用程序.在尝试对我的演示者进行单元测试并使用以下模式时,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);
Run Code Online (Sandbox Code Playgroud)

如何验证演示者是否正在执行预期的操作,即注册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();
}
Run Code Online (Sandbox Code Playgroud)

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

Joh*_*nny 31

moq 4.13介绍了此功能。现在可以验证是否add\remove已被调用。因此引入了四种新方法:

  1. SetupAdd
  2. SetupRemove
  3. VerifyAdd
  4. VerifyRemove

例子

var mock = new Mock<IAdder<EventArgs>>();
mock.SetupAdd(m => m.Added += (sender, args) => { });

mock.Object.Added += (sender, args) => { };
mock.Object.Added += (sender, args) => { };

mock.VerifyAdd(m => m.Added += It.IsAny<EventHandler>(), Times.Exactly(2));
Run Code Online (Sandbox Code Playgroud)

注意:请注意,为了验证至少应添加一个设置。原因是为了保持与旧版本的向后兼容moq

  • 另外,从版本“4.15.1”开始,我们不需要“SetupAdd”,我们只能使用“Verify” (2认同)

Mar*_*ath 15

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

可能值得问一个问题,"为什么SomePresenter需要订阅View LoadInit事件?" 据推测,这是因为SomePresenter班级需要回应这些事件.所以最好使用Raise你的方法Mock<IView>来引发LoadInit事件,然后声明SomePresenter做出正确的事情来回应它们.