消息框和单元测试

本文关键字:单元测试 消息 | 更新日期: 2023-09-27 18:18:21

我正在尝试找到将消息框与我的逻辑分离的最佳方法,以便我可以正确地对其进行单元测试。现在我想知道如果我只创建一个单独的帮助程序类 (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(...(。使用布尔显示,我可以在测试期间启用或禁用它。

我只是想知道这是否是"正确的方式"。我的意思是,有没有更简单或更好的方法来正确执行此操作?我不能只是放弃消息框,它们将"重要"信息传递给用户("你想关闭这个窗口吗?是/否等(。也可能只是我没有使用适当的软件工程,我应该更多地将我的消息框与我的业务逻辑分离?

消息框和单元测试

是的,这是正确的方式。但是,您应该实现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 容器将接口绑定到应用的特定实现。为了在您的情况下轻松实现这一点,请将消息框作为接口传递,并在单元测试中创建该消息框服务的模拟(假(版本,该服务不显示消息框

查看 http://martinfowler.com/articles/injection.html 以获取有关 IoC 的详细信息,我最喜欢的容器是 Ninject(http://ninject.org(

理想情况下,您希望使用单元测试测试的代码是逻辑代码,而不是 UI。因此,测试的逻辑不应真正显示消息框。如果你想测试 UI,那么我建议编码的 UI 测试。

从你的问题来看,我想你的代码不应该真的使用MessageBox。也许可以考虑使用回调或任意Action,或者卢克·麦格雷戈和谢尔盖五世提到的方法。

">

单元测试",就其确切含义而言,是对原子行为的测试。这不是您可以为代码进行的唯一一种代码驱动测试。特别是对于使用您提到的"是/否"对话框测试较长的方案,更大规模的代码驱动测试通常比单元测试更有效。

但是,为了能够更轻松地编写它们,最好不仅像Sergii提到的那样创建一个特殊服务,而且还要使其调用异步:

public interface IDialogService
{
    Task<bool> ShowYesNoMessageBox(...);
    ...
}

通过将消息框包装在非异步服务调用中并模拟它们,对于较长的场景,您将开始与"排列-操作-断言"模式相矛盾,方法是在用户操作实际发生之前预测用户操作(执行"安排"而不是"操作"(,这可能会在测试中引起许多问题,尤其是在使用 BDD/SpecFlow 完成测试时。使这些调用异步可以避免此类问题。请参阅我的博客文章,了解使用消息框进行更大规模测试的详细信息和示例。