单元测试MessageBox的函数

时间:2018-03-07 07:08:35

标签: c# unit-testing messagebox

我有一个自定义消息框的功能,如

public bool SomeFunction()
{
   MessageBoxResult mResult= MessageBox.Show("Displaying message");
   bool result;
   if(mResult == MessageBoxResult.OK)
   {
     result = AnyFunction();
   }
    return result;
}

我想为这些方法编写单元测试,而不显示消息框。有没有办法做到这一点?我正在使用' Microsoft.VisualStudio.TestTools'

3 个答案:

答案 0 :(得分:2)

这可能是一种使用moq的方法。我们的想法是隐藏界面背后的真实消息框实现,然后根据您在测试中想要实现的内容来模拟其行为。

<强>实施

public interface IMessageBox
{
    MessageBoxResult Show(string msg);
}

public class SomeClass
{
    private readonly IMessageBox _messageBox;

    public SomeClass(IMessageBox messageBox)
    {
        _messageBox = messageBox;
    }

    public bool SomeFunction()
    {
        MessageBoxResult mResult = _messageBox.Show("Displaying message");
        bool result;
        if(mResult == MessageBoxResult.OK)
        {
            result = AnyFunction();
        }
        return result;
    }
}

单元测试:

Mock<IMessageBox> messageBoxMock = new Mock<IMessageBox>();
messageBoxMock.Setup(m => m.Show(It.IsAny<string>()))
    .Returns(MessageBoxResult.OK); //can be whatever depends on test case
SomeClass sut = new SomeClass(messageBoxMock.Object);

答案 1 :(得分:1)

通常,当你有静态类的方法调用时,为了使代码可测试,为静态类创建包装类并将包装器注入客户端。

public interface IMessageBoxWrapper 
{
     MessageBoxResult Show(string message);
}

public class MessageBoxWrapper : IMessageBoxWrapper
{

    public MessageBoxResult Show(string message)
    { 

        return MessageBox.Show(message);
    }
 }

 public class SomeClass 
 {

      private readonly IMessageBoxWrapper _messageBox;

      public SomeClass(IMessageBoxWrapper messageBox)
      {
          _messageBox = messageBox;
      }

      public void SomeFunction()
      {              
          MessageBoxResult mResult= _messageBox.Show("Displaying message");
          bool result;
          if(mResult == MessageBoxResult.OK)
          {
            result = AnyFunction();
          }
          return result;
      } 
 }

答案 2 :(得分:0)

关于此主题的答案很多,从创建自定义类到使用第三方库不等。我想说的是,如果您想要带有漂亮视觉效果的炫酷弹出窗口,请使用第三方库。

但是,如果您只想将Microsoft的常规消息框用于WPF应用程序,则这里是MVVM /单元测试友好的实现:

最初,我以为我只是从消息框继承并用接口包装它,但由于消息框没有公共构造函数而无法这样做,所以这是“简单”的解决方案:

在Visual Studio中的反编译消息框中,您可以看到所有方法重载,我检查了我想要的重载,然后创建了一个新类并添加了方法,并用接口和ta-da对其进行了包装!现在,您可以使用ninject绑定接口和类,注入它,然后使用Moq对e.t.c进行单元测试。

创建一个接口(仅添加了一些重载,因为我不需要全部重载):

public interface IMessageBox
    {
        /// <summary>Displays a message box that has a message, title bar caption, and button; and that returns a result.</summary>          
        MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button);

    /// <summary>Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.</summary>           
    MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);

    /// <summary>Displays a message box that has a message and title bar caption; and that returns a result.</summary>            
    MessageBoxResult Show(string messageBoxText, string caption);
}

然后,我们有了将从其继承的类:

public class MessageBoxHelper : IMessageBox
    {
        /// <summary>Displays a message box that has a message, title bar caption, button, and icon; and that returns a result.</summary>            
        public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button,
            MessageBoxImage icon)
        {
            return MessageBox.Show(messageBoxText, caption, button, icon, MessageBoxResult.None,
                MessageBoxOptions.None);
        }

    /// <summary>Displays a message box that has a message, title bar caption, and button; and that returns a result.</summary>            
    public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
    {
        return MessageBox.Show(messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None,
            MessageBoxOptions.None);
    }

    /// <summary>Displays a message box that has a message and title bar caption; and that returns a result.</summary>            
    public MessageBoxResult Show(string messageBoxText, string caption)
    {
        return MessageBox.Show(messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None,
            MessageBoxResult.None, MessageBoxOptions.None);
    }

    /// <summary>Displays a message box that has a message and that returns a result.</summary>           
    public MessageBoxResult Show(string messageBoxText)
    {
        return MessageBox.Show(messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None,
            MessageBoxResult.None, MessageBoxOptions.None);
    }
}