繁体   English   中英

如何对已引发基于UI的事件进行单元测试?

[英]How to unit test that an UI-based event has been raised?

我想用MSTest编写单元测试,以验证更改控制元素后是否已调用某个事件。 不幸的是,用下面的代码永远不会调用comboBoxComPort(这是WinForms控件)的事件处理程序“ comboBoxComPort_SelectedIndexChanged”。 当然,这会导致不调用测试代码中的匿名处理程序。

[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”处理程序:

public class ConfigUI
{
     [...]

     private void comboBoxComPort_SelectedIndexChanged(object sender, EventArgs e)
     {
         DirtyEvent();
     }
 }

谁能告诉我为什么测试失败? 我知道在单元测试中访问私有成员通常不是一个好主意,但是我看不到测试UI行为的更好方法。 当然也欢迎对此提出建议。

这是您的注册处理程序吧?

 target.DirtyEvent += delegate
{
    dirtyEventCalled = true;
};

如果确实引发了事件,则并不意味着在不允许事件“冒泡或隧穿”时将调用处理程序...根据上下文,可以将事件视为在第一个处理程序收到控制权时处理。 WPF对此概念特别挑剔,它迫使处理程序将ISHandled位设置为false,以使事件在其他地方浮动。

如果你可以的话; 在事件的第一个处理程序中设置断点,然后在该事件的测试中设置断点。 重新启动应用程序,并确保首先确保第一个处理程序将看到它。 退出之前,请先查看该处理程序中的事件数据。 在第一个处理程序退出时,如果未调用您的测试处理程序,则是因为该事件被视为“已满足”。 这应该使您更接近找到解决方案。

我将为ConfigUI类引入一个接口(因为您希望看到控件在该类上调用方法,对吗?),然后使用Moq库在测试中模拟ConfigUI并使用Moq.Verify来查看方法被调用(您可以要求验证以说出多少次,依此类推...)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM