使用Moq,我是否总是需要模拟所有依赖项?

时间:2013-02-23 17:58:48

标签: unit-testing dependency-injection refactoring mocking moq

我在100多项测试中都有以下几行:

var registry = new Mock<ObjectRegistry>(new List<Assembly>()).Object;

一点点重构将我的ObjectRegistry构造函数改为:

public ObjectRegistry(AssemblyRegistry assemblies, UserPromt userPromt)

所以我必须更新所有100个测试用例以改为使用以下模拟:

var objectRegistry = new Mock<ObjectRegistry>(Mock.Of<AssemblyRegistry>(), Mock.Of<UserPromt>());

我想要的是所有依赖项都是模拟的,不管我需要什么依赖项都是不变的。

我可以告诉Moq以某种方式自动模拟它所需的所有依赖项吗?

在使用Mockito的java中,这根本不是问题......

2 个答案:

答案 0 :(得分:3)

你在这里嘲笑一个具体的对象。当与界面一起使用时,Moq效果最佳。尝试mock roles, not objects(pdf)。例如,引入诸如IObjectRegistry之类的接口。目前,您的代码知道它正在处理ObjectRegistry,理想情况下,您应该能够随时切换实现。为您提供抽象。对于可测试性和编程最佳实践而言,它将是“编程到接口”的理想选择。注意这里的接口并不一定意味着C#/ Java等接口。

var registry = new Mock<IObjectRegistry>();

public class ObjectRegistry : IObjectRegistry { // Snip }

然后使用它。由于这是一个接口,您可以根据需要随意更改具体(实际/生产)类及其构造函数。您的测试和系统的其余部分应该不知道。如果注册表在接口上有一个方法,例如GetObject,那么你的系统应该只依赖于这个抽象,而不是它正在使用ObjectRegistry实例。

目前,您的代码实际上正在创建ObjectRegistry的实际实例,然后存根/模拟相关方法。在大多数情况下,这并不理想。

答案 1 :(得分:1)

您的问题的最佳实践是使用接口而不是具体类,并通过这些接口传递依赖项。

public ObjectRegistry(IAssemblyRegistry assemblies, IUserPromt userPromt)