如何实现IDialogService来包装Messsage.Box以进行测试

时间:2016-01-20 00:25:54

标签: c#

我需要对Nunit进行一些单元测试,发现我对MessageBox.Show的调用正在阻碍。我正在查看IDialogService并试图实现它。

这是界面。

 namespace Exec.Core.Interfaces
    {
      public interface IDialogService
      {

        DialogResult ShowMessageBox(string text, string caption, MessageBoxButtons buttons);

        DialogResult ShowMessageBox(string text, string caption);

       DialogResult ShowMessageBox(string text);
      }
    }

这是实施。

namespace Exec.Core
{
  public interface IDialogService
  {
 }

    public  DialogResult ShowMessageBox(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
    {
      return MessageBox.Show( text,  caption, buttons,  icon);
    }

    public  DialogResult ShowMessageBox(string text, string caption, MessageBoxButtons buttons)
    {
      return MessageBox.Show(text, caption, buttons);
    }
 }
}

这里它正在进入一个类

namespace JobExec.Modules.Tasks
{
private  IDialogService dialogService;


     public partial class frmTask : form
     {
        private void Load_Form( object sender, EventArgs e)
        {
           dialogService = new DialogService();

            other stuff
        }
    }

}

我对目标的理解是我试图在Message.Box周围包装一个类,以便我可以用NSubstitute模拟它

我能让它工作的唯一方法是load_form事件中的行dialogService = new DialogService();

似乎我需要将private IDialogService dialogService;添加到每个类的顶部,并dialogService = new DialogService();添加到每个类的每个构造函数中。

这看起来非常臭。

我的方法是否正确?

谢谢,

科林

1 个答案:

答案 0 :(得分:2)

将接口的实例传递给表单构造函数更为常见。

关键是,您无法在表单中调用new DialogService(),因为这样就无法将其替换为实际上未显示MessageBox的版本。

然后,当谈到单元测试时,你可以传入IDialogService的模拟实现,它不显示MessageBox。

这是依赖注入。有些人使用DI框架但你不需要这个框架。如果你有一个包含大量依赖关系的大型对象图,那么使用框架可以在设置之后更容易管理。

当然还有其他方法:你可以说有一些静态的DialogServiceFactory可以在运行时更改,然后从每个模块引用,甚至可以像服务定位器那样引用。

请注意,您需要保留设计器支持的默认构造函数,并从注入构造函数中调用它。