消息框和unit testing

我正在尝试找到从我的逻辑中解开消息框的最佳方法,以便我可以正确地对其进行unit testing。 现在我想知道如果我只是制作了一个单独的帮助类(C#)就足够了,我可以稍后为我的消息框存根。 例如:

static class messageBoxHelper { public static void msgBoxAlg(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icons, bool show) { if (show) { MessageBox.Show(message, title, buttons, icons); } } 

然后,每当我需要使用消息框时,我只使用messageboxHelper / msgBoxAlg(…)而不是messagebox.show(…)。 使用bool show我可以在测试期间启用或禁用它。

我只是想知道这是否是“正确的方法”。 我的意思是,有更简单或更好的方法来做到这一点吗? 我不能只丢弃消息框,他们将“重要”信息传递给用户(“你想关闭这个窗口吗?”是/否等)。 它也可能只是我没有使用适当的软件工程,我应该将我的消息框与我的bussinesslogic分开更多?

是的,这是正确的方式。 但是,您应该实现IDialogService并将其注入应显示对话框的类中,而不是静态类:

 public interface IDialogService { void ShowMessageBox(...); ... } public class SomeClass { private IDialogService dialogService; public SomeClass(IDialogService dialogService) { this.dialogService = dialogService; } public void SomeLogic() { ... if (ok) { this.dialogService.ShowMessageBox("SUCCESS", ...); } else { this.dialogService.ShowMessageBox("SHIT HAPPENS...", ...); } } } 

在测试SomeClass期间,您应该注入IDialogService模拟对象而不是真实对象。

如果需要测试更多UI逻辑,请考虑使用MVVM模式。

查看控制反转(IoC),基本原则是执行操作的事物应该作为接口传递,然后使用IoC容器将接口绑定到应用程序的特定实现。 为了在您的情况下轻松实现这一点,将作为接口的消息框的内容传递给您的unit testing创​​建该消息框服务的模拟(假)版本,该服务不显示消息框

有关IoC的详细信息,请访问http://martinfowler.com/articles/injection.html ,我最喜欢的容器是Ninject(http://ninject.org)

理想情况下,您希望使用unit testing进行测试的代码是逻辑而不是UI。 因此,您的测试逻辑不应该真正显示消息框。 如果您想测试用户界面,那么我会建议编码用户界面测试 。

根据您的问题判断,我认为您的代码不应该使用MessageBox 。 也许考虑使用回调或任意Action ,或Luke McGregor和Sergey V.提到的方法。

“unit testing”,其确切含义,是对primefaces行为的测试。 这不是您可以为代码进行的唯一一种代码驱动的测试。 特别是对于使用“是/否”对话框测试更长的场景,大规模代码驱动的测试通常比unit testing更有效。

但是为了能够更容易地编写它们,不仅可以创建Sergii提到的特殊服务,还可以使其调用异步:

 public interface IDialogService { Task ShowYesNoMessageBox(...); ... } 

通过将消息框包装在非异步服务调用中并模拟它们,对于更长的情况,您将开始通过在实际发生之前预测用户操作来对抗“Arrange-Act-Assert”模式(执行“Arrange”而不是“Act”),这会导致测试中出现许多问题,特别是如果您的测试是使用BDD / SpecFlow完成的。 使这些调用异步可以避免这些问题。 有关详细信息和使用消息框进行大规模测试的示例,请参阅我的博客文章 。