我有一个自定义消息框的功能,如
public bool SomeFunction()
{
MessageBoxResult mResult= MessageBox.Show("Displaying message");
bool result;
if(mResult == MessageBoxResult.OK)
{
result = AnyFunction();
}
return result;
}
我想为这些方法编写单元测试,而不显示消息框。有没有办法做到这一点?我正在使用' Microsoft.VisualStudio.TestTools'
答案 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);
}
}