我的应用程序由各种具体的Job类组成(所有类都继承自抽象的Job类)。在他们的Run()方法中,他们通常调用外部服务。 我想测试我的工作类并模拟服务结果。
以下是典型的具体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框架进行模拟。
答案 0 :(得分:3)
一些选择:
工厂服务方法的快速示例:
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...
}
}
这当然假设您的WpManager具有可以模拟的虚拟方法。如果没有,你也需要提取一个IWpManager接口,然后再模拟它。
答案 1 :(得分:0)
在消费者类中实例化具体类违反了SOLID原则之一(“D”或“依赖注入”)。其中一个原因是您遇到的问题: testability 。
我建议你让WpManager
取一个IInstallWpJobResult
的实例(注意它是一个接口)作为其构造的一部分,而不是实例化它。通过这种方式,您可以轻松更改给定不同IInstallWpJobResult
实现的类的行为,例如传递具有预定义行为的Mock<IInstallWpJobResult>
以便于测试。
一旦开始使用依赖注入框架在运行时解析所有这些依赖项,这也会派上用场,因为它们通常会查看构造函数的参数,以了解要注入的依赖项。