C#,Nunit,Moq如何测试演示者是否订阅了它';我们看什么?

C#,Nunit,Moq如何测试演示者是否订阅了它';我们看什么?,c#,unit-testing,nunit,moq,mvp,C#,Unit Testing,Nunit,Moq,Mvp,我认为谁是winform: public partial class View : Form, IView { private static object eventsLock = new Object(); private EventHandler CustomClick; public View() { InitializeComponent(); this.button.Click += FireCustomClickEve

我认为谁是winform:

public partial class View : Form, IView
{
    private static object eventsLock = new Object();
    private EventHandler CustomClick;

    public View()
    {
        InitializeComponent();
        this.button.Click += FireCustomClickEvent;
    }

    event EventHandler IView.Click
    {
        add { lock (eventsLock) { this.CustomClick += value; }}
        remove { lock (eventsLock) { this.CustomClick -= value; }}
    }

    private void FireCustomClickEvent(object sender, EventArgs e)
    {
        this.CustomClick?.Invoke(sender, e);
    }

    public void MakeViewDoStuff()
    {
        //Do stuff...
    }
}
IView
界面如下:

public interface IView
{
    event Eventhandler Click;
    void MakeViewDoStuff();
}
我有一位演讲者:

public class Presenter : IPresenter
{
    private IView view;
    public Presenter(IView view)
    {
        this.view = view;
        this.AttachView();
    }

    private void AttachView()
    {
        this.view.Click += SomePresenterStuff;
    }

    private void SomePresenterStuff(object sender EventArgs e)
    {
        this.view.MakeViewDoStuff();
        //Do stuff now that the event was raised.
    }
}
现在,我可以测试是否引发了事件,演示者是否使用此测试函数让视图执行操作:

this.mockedView.Raise(v => v.Click += null, new System.EventArgs());
this.mockedView.Verify(v => v.MakeViewDoStuff(), Times.Once());
但我想知道的是:我是否应该测试演示者是否附加到其构造函数中

因此,基本上,我应该测试在Presenter的构造函数中调用了
private void AttachView()
,我该怎么做

一些注意事项:

我认为添加一个布尔标志来保持演示者的连接状态是一种糟糕的做法,因为它将涉及更改生产代码,只为了能够对其进行测试,而不会在生产中使用

编辑:


我有点同意Sergey Berezovskiy的观点,这可能不是演讲者的责任,也不是一种行为,但是如果我的观点有一个近距离观看事件,当提出时,演讲者应该取消订阅观看事件。难道我们不想测试一下吗?

我认为演讲者的责任是

通过执行某些操作来响应视图的单击事件

如果发生这种情况,谁会在乎演示者是如何与活动联系在一起的?这只是与业务逻辑无关的技术细节。您当前的测试准确地验证了应该验证的内容

有很多技术上的东西你可以验证

  • 演示者是否在“专用”字段中存储视图
  • 演示者是否附加到事件
  • 演示者是否随时间保持连接

但是,演示者以所需的方式对视图的事件做出反应并不重要。

您可能希望在模拟视图中检查这一点,但是@stuartd感谢此链接非常有用。假设我有这样一个场景:我的视图有一个关闭的事件,演示者在其引发时应退出视图。如果要测试事件注册,这不是一个有效的案例吗?或者我应该在演示者的析构函数中取消连接视图吗?@Sebastien是的,我认为这是一个有效的业务需求-演示者应该对关闭事件做出反应,以便任何进一步的事件都不会有反应