【问题标题】:Testing if a messagebox was successfully shown in a unit test测试消息框是否在单元测试中成功显示
【发布时间】:2016-12-30 16:57:41
【问题描述】:

希望这很简单,但我一直在努力解决这个问题。

如果我有一个简单的类,它的方法应该做某事,然后当某些值处于某种状态时通过 MessageBox.Show("") 显示一个消息框,我该如何编写一个测试/测试可以检测消息框是否按预期显示和/或未按预期显示?

【问题讨论】:

  • 我会隐藏在界面后面显示消息框。然后模拟那个接口并在你的模拟实现中创建一个计数器或类似的东西。
  • 那是不是单元测试。这就是 UI 测试。您可以使用 Accessibility API 或 Visual Studio 的 UI 测试项目(使用 Accessibility API)
  • 你能分享一下你想测试的方法和你开始编写的潜在单元测试吗?
  • 您不需要测试 MessageBox.Show 方法,因为它来自框架。您需要测试您的代码是否采用正确的路径并将正确的值传递给 Show() 方法。所以模拟接口是进行单元测试的正确方法。
  • @Dan 如果您使用 MVVM 或类似模式将 UI 与业务代码分开,那会更好。通过这种方式,您可以确保控制器/模型/任何东西发出正确的通知,并使用更简单的 UI/集成测试来确保您的 UI 显示适当的内容以响应这些通知

标签: c# unit-testing messagebox


【解决方案1】:

您无法通过单元测试对其进行真正的测试。不过,有一种简单的方法可以测试代码是否被正确调用。

我会隐藏在界面后面显示MessageBox。然后模拟该接口并在您的模拟实现中创建一个计数器或类似的东西。当然,您可以根据需要使其具体化,提供显示的消息等。

【讨论】:

  • 更好的选择是使用 MVVM 或类似的模式将 UI 与后端代码分开。您可以对控制器/模型进行单元测试,并对瘦 UI 视图使用 UI 测试
  • 当然,这通常需要对程序进行整个返工。这种解决方案更容易实现,作为最终一直使用 MVVM 的一种方式。
  • 刚才OP在评论中提到“方法相当大”。这意味着它必须独立于 UI 进行单元测试。顺便提一句。 .NET 已经提供了IProgress<T> 接口,该接口在引发通知时提供事件和回调。这使得单元测试更容易一些
【解决方案2】:

您不应该测试 MessageBox 是否出现,尽管可以使用一个或另一个 UI 自动化框架(如 https://msdn.microsoft.com/en-us/library/ms747327(v=vs.110).aspx)来测试。

但这不会是单元测试。应该是automated UI test

所以,如果你想创建一个合适的单元测试,那么你的类应该是 injectable 和一些

public interface IMessageBox
{
    void Show(String message);
}

public class SUT
{
    public SUT(IMessageBox messageBox)
    {   
        this._messageBox = messageBox;
    }

    public void Test()
    {
        this._messageBox.Show("TEST);
    }
}

这样你就可以mock unittest 中的那个 IMessageBox。

例如,Moq:

[TestMethod]
public void Test()
{
    // Arrange
    var messageBox = new Mock<IMessageBox>();
    messageBox
        .Setup(m =>
            m.Show("TEST))
        .Verifiable();

    var sut = new SUT(messageBox.Object);

    // Act
    sut.Test();

    // Verify
    messageBox.Verify();        
}

【讨论】:

  • .NET 已经提供了IProgress 接口。此外,接口不应与其实现绑定,例如IMessageBox
  • @PanagiotisKanavos 你说得对,使用更通用的IProgress 调解器将该类与 UI 职责分离可能是一个好主意。虽然这取决于实际系统。但我不明白“与其实施相关”的部分? IMessageBox 与其实现相关联的唯一方法是通过它的名称,并且可以更改。没有人阻止任何人实现某些 ConsoleMessageBox,例如Console.WriteLine(message); Console.ReadKey();IMessageBox 有明确的责任 - 只是这样的接口不应该在业务逻辑的深处使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
  • 2017-05-16
  • 2019-09-06
相关资源
最近更新 更多