我有一些单元测试可以调用ApplicationShouldBeInstalled(app)来确保它正常工作。下面的实际生产代码也调用了该方法,因此它不会意外地安装应用程序。但是,没有什么可以阻止开发人员删除执行检查的代码行。我的单元测试无法捕捉到这一点,因为测试的是ApplicationShouldBeInstalled(app)方法,而不是InstallApplications()方法。
我不能从我的测试代码调用InstallApplications(),因为它会试图安装一个应用程序。InstallApplication(app)是同一类中的一个方法,而不是我可以用接口模拟它的另一个类。有没有办法确保InstallApplications()总是执行这种检查?我想我可以将ApplicationShouldBeInstalled(app)移动到另一个类并模拟它,但然后我只是为了测试/模拟而移动代码。有没有更好的方法?
public void InstallApplications()
{
foreach (App app in this._apps)
{
if (!ApplicationShouldBeInstalled(app)) { continue; }
InstallApplication(app);
}
}mocking选项将如下所示。Container会在实时运行时返回真正的实现,并在运行测试时返回一个模拟。
public void InstallApplications()
{
foreach (App app in this._apps)
{
if (!ApplicationShouldBeInstalled(app)) { continue; }
Container.Resolve<IInstaller>().InstallApplication(app);
}
}发布于 2013-02-15 03:57:52
是,从处理安装的代码中删除控制是否应安装应用程序的策略的代码。这将允许您单独测试这两段代码,并确信每段代码都在做您需要的事情。我甚至会在这里有3个合作者。控制循环的代码、控制策略验证的代码,最后是执行安装的代码。三个部分,可独立测试,更容易验证。
foreach (var app in this._apps)
{
if (!applicationInstallationPolicyProvider.CanInstall(app)) // can be mocked away
{
continue;
}
applicationInstaller.Install(app); // can also be mocked away
}我想对你来说关键是你在问题中说“你不能在测试中运行安装代码”。但是,重要的是要验证循环是否会在需要时实际调用安装代码。这应该是足够的动机来尝试隔离它,无论你是否达到我可能喜欢的程度。
发布于 2013-02-15 03:58:44
当您将其提取到接口时,您并没有真正删除属于该类的代码。您正在要求类实现成员。使用接口的一个主要好处是,它允许您模拟它们,因此您实际上不需要更改功能。您模拟接口,然后验证特定的方法实际上正在做您期望它做的事情。
另外,它还允许您使用依赖注入,这样您就不会经常在内存中创建对象的实例。
https://stackoverflow.com/questions/14882849
复制相似问题