我需要对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();
添加到每个类的每个构造函数中。
这看起来非常臭。
我的方法是否正确?
谢谢,
科林
答案 0 :(得分:2)
将接口的实例传递给表单构造函数更为常见。
关键是,您无法在表单中调用new DialogService()
,因为这样就无法将其替换为实际上未显示MessageBox的版本。
然后,当谈到单元测试时,你可以传入IDialogService
的模拟实现,它不显示MessageBox。
这是依赖注入。有些人使用DI框架但你不需要这个框架。如果你有一个包含大量依赖关系的大型对象图,那么使用框架可以在设置之后更容易管理。
当然还有其他方法:你可以说有一些静态的DialogServiceFactory可以在运行时更改,然后从每个模块引用,甚至可以像服务定位器那样引用。
请注意,您需要保留设计器支持的默认构造函数,并从注入构造函数中调用它。