我在C# Winforms中实现了MVP(MVC)模式。
我的视图和Presenter如下(没有所有的MVP粘合剂):
public interface IExampleView
{
event EventHandler<EventArgs> SaveClicked;
string Message {get; set; }
}
public partial class ExampleView : Form
{
public event EventHandler<EventArgs> SaveClicked;
string Message {
get { return txtMessage.Text; }
set { txtMessage.Text = value; }
}
private void btnSave_Click(object sender, EventArgs e)
{
if (SaveClicked != null) SaveClicked.Invoke(sender, e);
}
}
public class ExamplePresenter
{
public void OnLoad()
{
View.SaveClicked += View_SaveClicked;
}
private async void View_SaveClicked(object sender, EventArgs e)
{
await Task.Run(() =>
{
// Do save
});
View.Message = "Saved!"
}
我正在使用MSTest进行单元测试,同时使用NSubstitute进行模拟。我想在视图中模拟按钮点击以测试控制器的View_SaveClicked
代码,如下:
[TestMethod]
public void WhenSaveButtonClicked_ThenSaveMessageShouldBeShown()
{
// Arrange
// Act
View.SaveClicked += Raise.EventWith(new object(), new EventArgs());
// Assert
Assert.AreEqual("Saved!", View.Message);
}
我能够成功地使用NSubstitute的Raise.EventWith触发View.SaveClicked事件。然而,问题在于代码立即转到Assert语句,此时Presenter还没有足够时间保存消息,因此Assert失败。
我理解这是为什么,并已经成功地通过添加Thread.Sleep(500)来绕过它,但这不是最佳选择。我也可以更新我的视图以调用presenter.Save()方法,但尽可能使视图对Presenter不可知是我的目标。
因此,我想知道如何改进单元测试,以等待async View_SaveClicked完成,或更改View/Presenter代码以使它们在此情况下更容易进行单元测试。
有任何想法吗?