Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 移动模拟的方法?_C#_Unit Testing_Mocking - Fatal编程技术网

C# 移动模拟的方法?

C# 移动模拟的方法?,c#,unit-testing,mocking,C#,Unit Testing,Mocking,我有一些单元测试调用应用程序shouldbeinstalled(app),以确保它正常工作。下面的实际生产代码也调用该方法,因此不会意外安装应用程序。但是,没有什么可以阻止开发人员删除执行检查的代码行。我的单元测试不会捕捉到这一点,因为测试是测试应用程序应安装(app)方法,而不是InstallApplications()方法 我无法从测试代码中调用InstallApplications(),因为这样它将尝试安装应用程序InstallApplication(app)是同一个类中的一个方法,而不是

我有一些单元测试调用
应用程序shouldbeinstalled(app)
,以确保它正常工作。下面的实际生产代码也调用该方法,因此不会意外安装应用程序。但是,没有什么可以阻止开发人员删除执行检查的代码行。我的单元测试不会捕捉到这一点,因为测试是测试
应用程序应安装(app)
方法,而不是
InstallApplications()
方法

我无法从测试代码中调用
InstallApplications()
,因为这样它将尝试安装应用程序
InstallApplication(app)
是同一个类中的一个方法,而不是我可以用接口模拟它的另一个类。是否有办法确保InstallApplications()始终执行该检查?我想我可以将
应用程序shouldbeinstalled(app)
移动到另一个类并模拟它,但是我移动代码只是为了测试/模拟。有更好的办法吗

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

        InstallApplication(app);
    }                       
}
模拟选项如下所示。
容器
将在运行live时返回实际实现,在运行测试时返回模拟

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

        Container.Resolve<IInstaller>().InstallApplication(app);
    }                       
}
public-void-InstallApplications()
{
foreach(此中的应用程序。\u应用程序)
{
如果(!ApplicationShouldBeInstalled(app)){continue;}
Container.Resolve().InstallApplication(应用程序);
}                       
}

是,从处理安装的代码中删除控制是否应安装应用程序的策略的代码。这将允许您单独测试这两段代码,并获得每个代码都在做您需要的事情的信心。我甚至会在这里有三个合作者。控制循环的代码,控制根据策略进行验证的代码,最后是执行安装的代码。三件式,可独立测试,易于验证

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

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

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

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


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

您能从该方法中提取接口,然后模拟接口吗?有关更多信息,请参阅我是否正确理解您,这是我在问题中列出的选项。所以,是的,我可以,但我想知道是否有更好的方法。在我看来,所有这些代码都属于它当前所在的类。不过,如果这是我测试它所必须做的,我会移动它。这符合我刚才添加到我的问题中的内容,所以我相信我走在了正确的道路上。谢谢我认为关键在于你在问题中说“你不能在测试中运行安装代码”,但对你来说,验证循环是否真的会调用安装代码应该很重要!这应该是足够的动机,试图孤立它。同意!现在就做。非常感谢。