我使用NUnit测试单位,我有一个方法:
class abc
{
private int a;
public void myMethod()
{
if(MessageBox.Show("Sure?", "Title", MessageBoxButtons.YesNo) == DialogResult.Yes)
a = 1;
else
a = 0;
}
}
如何编写NUnit来测试此方法?对不起我的英语不好。 非常感谢你。
答案 0 :(得分:3)
通常的解决方案是模拟MessageBox
类并模拟Show
方法返回的内容。由于它是一种静态方法,因此需要在代码中进行额外的工作和一些修改。这是一个可能的解决方案:
创建一个封装Show
方法的类:
public class MyMessageBox {
public virtual DialogResult Show(string text, string caption, MessageBoxButtons buttons) {
return MessageBox.Show(text, caption, buttons);
}
}
然后修改您的代码以使用该类:
class Abc {
internal int a;
private readonly MyMessageBox messageBox;
public Abc(MyMessageBox messageBox) {
this.messageBox = messageBox;
}
public void MyMethod() {
if (messageBox.Show("Sure?", "Title", MessageBoxButtons.YesNo) == DialogResult.Yes)
a = 1;
else
a = 0;
}
}
之后,您可以编写模拟MyMessageBox
类的测试。我在下面的示例中使用NSubstitute:
[Test]
public void Test() {
MyMessageBox messageBox = Substitute.For<MyMessageBox>();
messageBox.Show("Sure?", "Title", MessageBoxButtons.YesNo).Returns(DialogResult.Yes);
Abc abc = new Abc(messageBox);
abc.MyMethod();
Assert.AreEqual(1, abc.a);
}
这是一种方法。由您来决定是否值得付出努力。
答案 1 :(得分:0)
我建议使用一些设计模式来实现这一目标。
- MVVM(你可以从Nuget获得一个名为MVVMLight的超级库)
- 依赖注入
- 控制倒置
- 存储库模式
因此,在顶级视图中只存在对MessageBox的调用。像这样的东西 -
Messenger.Default.Register<DialogMessage>(this, ProcessMessage);
private static void ProcessMessage(DialogMessage message)
{
var result = MessageBox.Show(
message.Content,
message.Caption,
message.Button);
message.Callback(result);
}
所以,现在当你运行单元测试 -
[Test]
public void Some_Test ()
{
//Arrange
string expected_msg = "";
Messenger.Default.Register<DialogMessage>(this, (o) => {expected_msg=o.Content ;});
CreateSUT();
//Act
..do something here that involves calling that MessageBox
//Assert
Assert.That(expected_msg, Is.EqualTo(<Some Msg you are sending from ViewModel>));
}
当从ViewModel以这样的方式调用时,此单元测试捕获对MessageBox的调用 -
Messenger.Default.Send(new DialogMessage("<Some Message you are sending from viewmodel>", delegate { })
{
Button = MessageBoxButton.OK,
Caption = "Alert",
Icon = MessageBoxImage.Exclamation
});