C#、Nunit、Moq 如何测试演示者是否订阅了它的视图事件?
C#, Nunit, Moq How to test that a presenter is subscribed to it's view events?
我看谁是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 是否附加到其构造函数中?
所以基本上,我应该测试在 Presenter 的构造函数中调用 private void AttachView()
吗?我该怎么做?
一些注意事项:
我认为添加一个布尔标志来保持演示者的附加状态是一种糟糕的黑客攻击,因为它涉及更改生产代码只是为了能够测试它并且不会在生产中使用。
编辑:
我有点同意 Sergey Berezovskiy 的观点,这可能不是演示者的责任,也不是行为,但是如果我的视图有 CloseView 事件怎么办,当引发时,演示者应该取消订阅视图事件。我们不想测试一下吗?
我认为主持人的责任是
reacting to view's Click event by doing some stuff
如果发生这种情况 - 谁在乎演示者是如何参与活动的?那只是与业务逻辑无关的技术细节。您当前的测试准确地验证了应该验证的内容。
有很多技术资料你可以验证
- 演示者在私有字段中存储视图?
- 演示者加入了活动?
- 演示者会随着时间的推移保持联系?
但是当演示者以所需的方式对视图的事件做出反应时,这并不重要。
我看谁是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 是否附加到其构造函数中?
所以基本上,我应该测试在 Presenter 的构造函数中调用 private void AttachView()
吗?我该怎么做?
一些注意事项:
我认为添加一个布尔标志来保持演示者的附加状态是一种糟糕的黑客攻击,因为它涉及更改生产代码只是为了能够测试它并且不会在生产中使用。
编辑:
我有点同意 Sergey Berezovskiy 的观点,这可能不是演示者的责任,也不是行为,但是如果我的视图有 CloseView 事件怎么办,当引发时,演示者应该取消订阅视图事件。我们不想测试一下吗?
我认为主持人的责任是
reacting to view's Click event by doing some stuff
如果发生这种情况 - 谁在乎演示者是如何参与活动的?那只是与业务逻辑无关的技术细节。您当前的测试准确地验证了应该验证的内容。
有很多技术资料你可以验证
- 演示者在私有字段中存储视图?
- 演示者加入了活动?
- 演示者会随着时间的推移保持联系?
但是当演示者以所需的方式对视图的事件做出反应时,这并不重要。