我想用MSTest编写单元测试,用于验证控制元素更改后是否调用了某个事件。不幸的是,事件处理程序下面的代码" comboBoxComPort_SelectedIndexChanged"对于comboBoxComPort(这是一个WinForms控件)永远不会被调用。这当然会导致测试代码中的匿名处理程序无法被调用。
[TestMethod()]
public void ComboBoxComPort_SelectionChanged_DirtyEventFired()
{
ConfigUI target = new ConfigUI();
var accessibleTarget = new PrivateObject(target);
ComboBox comboBoxComPort = (ComboBox)accessibleTarget.GetField("comboBoxComPort");
bool dirtyEventCalled = false;
target.DirtyEvent += delegate
{
dirtyEventCalled = true;
};
comboBoxComPort.SelectedIndex = comboBoxComPort.Items.Count - 1;
Assert.IsTrue(dirtyEventCalled);
}
为简单起见,我们假设这是" SelectedIndexChanged" -handler:
public class ConfigUI
{
[...]
private void comboBoxComPort_SelectedIndexChanged(object sender, EventArgs e)
{
DirtyEvent();
}
}
有人可以告诉我测试失败的原因吗?我知道在单元测试中访问私有成员通常不是一个好主意,但我没有看到更好的方法来测试UI行为。当然也欢迎这方面的建议。
答案 0 :(得分:0)
这是您的注册处理程序吗?
target.DirtyEvent += delegate
{
dirtyEventCalled = true;
};
如果确实引发了事件,那么并不意味着当事件不允许“冒泡或隧道”时将调用处理程序...根据上下文,当第一个处理程序收到事件时,可以认为事件处理控制。 WPF对此概念特别挑剔,强制处理程序将ISHandled位设置为false,以使事件浮动到其他位置。
如果可以;在事件的第一个处理程序中设置断点,然后在该事件的测试中设置断点。重新启动应用程序,并首先确保第一个处理程序正在查看它。退出之前,请查看该处理程序中的事件数据。退出第一个处理程序后,如果未调用您的测试处理程序,则因为该事件被视为“满足”。这应该让你更接近找到解决方案。
答案 1 :(得分:0)
我将为ConfigUI类引入一个接口(因为你想看到一个控件在该类上调用一个方法,对吗?),然后使用Moq库在测试中模拟ConfigUI并使用Moq.Verify来看到方法被调用(你可以要求验证说多少次等等......)