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
C# 如何强制方法使用模拟?_C#_Unit Testing_Mocking_Moq - Fatal编程技术网

C# 如何强制方法使用模拟?

C# 如何强制方法使用模拟?,c#,unit-testing,mocking,moq,C#,Unit Testing,Mocking,Moq,我的应用程序由各种具体的作业类组成(都继承自抽象作业类)。在Run()方法中,它们通常调用外部服务。 我想测试我的职业课程并模拟服务结果 下面是一个典型的concrete Run()方法的外观: InstallWpJobResult result = new InstallWpJobResult(); WpManager wpManager = new WpManager(); if (!WpManager.InstallWp(Domain, SiteTitle, WpU

我的应用程序由各种具体的作业类组成(都继承自抽象作业类)。在Run()方法中,它们通常调用外部服务。 我想测试我的职业课程并模拟服务结果

下面是一个典型的concrete Run()方法的外观:

    InstallWpJobResult result = new InstallWpJobResult();
    WpManager wpManager = new WpManager();
    if (!WpManager.InstallWp(Domain, SiteTitle, WpUsername, WpPassword, WpEmail))
        result.Error = "Error installing WordPress";
    return result;
我希望WpManager.InstallWp返回true(在模拟版本中)。 我知道如何模拟对象和方法,但如何使我的工作使用模拟版本?(现在它在方法本身中创建了一个实例)

顺便说一句,我正在使用Moq框架进行模拟。

有几个选项:

  • 定义一个工厂服务IWpManagerFactory,该工厂服务IWpManagerFactory被注入到作业类中,并使用一个方法来构造模拟的WpManager
  • 在作业中定义一个虚拟方法BuildWpManager,并在测试中重写该方法以注入模拟

  • 工厂服务方法的快速示例:

    public interface IWpManagerFactory
    {
        WpManager BuildWpManager();
    }
    
    public sealed class Tests
    {
        public void Test()
        {
            var manager = new Mock<WpManager>();
            //Set up mock manager here...
    
            var factory = new Mock<IWpManagerFactory>();
            factory.Setup(f => f.BuildWpManager()).Returns(manager.Object);
    
            //Inject factory to class under test and execute the method under test...
        }
    }
    
    公共接口IWpManagerFactory { WpManager BuildWpManager(); } 公开密封等级考试 { 公开无效测试() { var manager=newmock(); //在这里设置模拟管理器。。。 var factory=new Mock(); factory.Setup(f=>f.BuildWpManager()).Returns(manager.Object); //将工厂注入测试中的类并执行测试中的方法。。。 } }
    当然,这假设您的WpManager具有可以模拟的虚拟方法。如果没有,您还需要提取一个IWpManager接口,然后模拟它。

    在使用者类中实例化具体类违反了一个坚实的原则(“D”或“依赖项注入”)。其中一个原因是您遇到的:可测试性

    我建议您让
    WpManager
    IInstallWpJobResult
    为例(注意它是一个接口)作为其构造的一部分,而不是实例化一个实例。通过这种方式,您可以在给定不同的
    IInstallWpJobResult
    实现的情况下轻松更改类的行为,例如,使用预定义的行为传入
    Mock
    ,以便于测试


    一旦您开始使用依赖项注入框架在运行时解析所有这些依赖项,这也会派上用场,因为它们通常会查看构造函数的参数以了解要注入的依赖项。

    我明白了。如果不是要求太高,你介意给我举一个像IWpManagerFactory这样的工厂的例子吗?我明白了。非常感谢,有道理:)