如何在 wpf 中测试 MessageBox?

Posted

技术标签:

【中文标题】如何在 wpf 中测试 MessageBox?【英文标题】:How to test a MessageBox in wpf? 【发布时间】:2020-12-15 00:24:04 【问题描述】:

我要做一些单元测试,但我正在努力解决MessageBox。我有一个MessageBox,它在我的代码中显示一个文本和一个“确定”按钮。当我尝试对包含MessageBox.Show("Text")的方法进行单元测试时,它也会在单元测试中弹出,我必须单击“确定”才能通过,这很糟糕。

有人知道怎么解决吗?我想我需要某种代码来伪造MessageBox 并单击“确定”,但我不知道该怎么做。我是一名初级程序员,所以请尽可能简单地解释它;)并很乐意提供一些代码示例。

这是我的MessageBox 代码:

public void GetPopUpWithErrorMessage()

   MessageBox.Show("Error Message", "text",
   MessageBoxButton.OK);

编辑 我刚刚意识到项目中使用了 Fluent Assertions。有谁知道如何在测试代码中实现它?和@thatguy 展示的一样吗?

【问题讨论】:

您需要创建一个显示消息的服务。在您的测试中,您应该模拟您的服务以防止出现消息框。 Fluent 断言仅提供扩展方法来提高测试结果的可读性,但这与模拟无关。你仍然需要一个模拟框架。它的工作原理与答案中显示的相同。您的测试代码应该与以前相同,不同之处在于您创建了一个模拟并将其传递给您的类,但这不会干扰流畅的断言。 啊,好吧!谢谢! :) 【参考方案1】:

您必须创建一个服务来实现可以在测试中模拟的接口。

public interface IMessageBoxService

   void ShowMessageBox(string title, string message);


public class MessageBoxService : IMessageBoxService

   public void ShowMessageBox(string title, string message)
   
      MessageBox.Show(message, title, MessageBoxButton.OK);
   

在你使用它的类中,你可以通过它的接口传递这个服务,例如在构造函数中,所以类只知道它的契约,而不知道它的实现。

public class MyClass

   private IMessageBoxService _messageBoxService;

   public MyClass(IMessageBoxService messageBoxService)
   
      _messageBoxService = messageBoxService;
   

   public void GetPopUpWithErrorMessage()
   
      _messageBoxService.ShowMessageBox("text", "Error Message");
   

在测试类中,您需要使用像Moq 这样的模拟框架,它从一个接口创建一个模拟对象,这只是一个存根,您可以使用它来为您使用的任何方法或属性注入行为你的测试。

在这个使用 NUnitMoq 的示例中,messageBoxService 被创建为实现 IMessageBoxService 接口的模拟对象。除非您指定它们应该做什么或通过Setup 返回,否则所有方法什么都不做,但这是另一个主题。最后一行显示了如何检查在测试期间是否调用了 mock 上的特定方法。

[TestFixture]
public class MyClassTest

   [Test]
   public void MyTest()
   
      var messageBoxService = Mock.Of<IMessageBoxService>();
      var myClass = new MyClass(messageBoxService);

      // ...your test code.

      // Checks if the "ShowMessageBox" method in the service was called with any strings
      Mock.Get(messageBoxService).Verify(mock => mock.ShowMessageBox(It.IsAny<string>(), It.IsAny<string>()));
   

创建服务和接口不仅对模拟有用,而且对于分离视图和逻辑也很有用,因为您可以将消息框的调用提取到具有隐藏在接口后面的实现的服务中。此外,您可以通过构造函数轻松实现依赖注入。

【讨论】:

谢谢,我会尝试在我的代码中做类似的事情,看看它是否有效! :)

以上是关于如何在 wpf 中测试 MessageBox?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WPF 中将 MessageBox 窗口保留在前台

wpf messagebox 的返回值如何获取

Winform与WPF对话框(MessageBox, Dialog)之比较

关闭 WPF 应用程序后 System.Windows.MessageBox.Show() 在后台保持打开状态

删除前的 MessageBox - wpf datagrid

来自非模态 WPF 窗口的应用程序模态 MessageBox