【问题标题】:Move Method for Mocking?Mocking 的移动方法?
【发布时间】:2013-02-14 19:49:41
【问题描述】:

我有单元测试调用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);
    }                       
}

模拟选项看起来像这样。 Container 将在实时运行时返回真正的实现,在运行测试时返回模拟。

public void InstallApplications()
{
    foreach (App app in this._apps)
    {
        if (!ApplicationShouldBeInstalled(app)) { continue; }

        Container.Resolve<IInstaller>().InstallApplication(app);
    }                       
}

【问题讨论】:

  • 能不能从方法中提取一个接口,然后mock这个接口?
  • 如果我理解正确,那是我在问题中列出的选项。所以,是的,我可以,但我想知道是否有更好的方法。 IMO,所有这些代码都属于它当前所在的类。不过,如果我必须这样做才能对其进行测试,我会移动它。

标签: c# unit-testing mocking


【解决方案1】:

是的,从处理安装的代码中删除控制是否应安装应用程序的策略的代码。这将允许您单独测试两段代码,并确信每段代码都在执行您的要求。我什至会在这里有 3 个合作者。控制循环的代码,控制验证策略的代码,最后是执行安装的代码。三件套,可独立测试,更容易验证。

foreach (var app in this._apps)
{
     if (!applicationInstallationPolicyProvider.CanInstall(app)) // can be mocked away
     {
          continue;
     }

     applicationInstaller.Install(app); // can also be mocked away
}

我认为对你来说关键是当你在问题中说“你不能在测试中运行安装代码”时。但对您来说,验证循环是否确实在需要时调用安装代码应该很重要。无论您是否达到我可能喜欢的程度,这应该已经足以成为尝试隔离它的动力。

【讨论】:

  • 这符合我刚刚添加到我的问题的内容,所以我相信我走在正确的道路上。谢谢!
  • 我认为对你来说关键是当你在问题中说“你不能在测试中运行安装代码”时。但对您来说验证循环实际上调用安装代码应该很重要!这应该是足够的动力来尝试隔离它。
  • 同意!现在就做。谢谢!
【解决方案2】:

当您将其提取到接口时,您并没有真正删除属于该类的代码。您需要该类来实现成员。使用接口的一个主要好处是它允许您模拟它们,这样您就不会实际更改功能。您模拟接口,然后验证特定方法是否确实在执行您期望的操作。

另一方面,它还允许您使用依赖注入,这样您就不会不断地在内存中创建对象实例。

【讨论】:

    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多