我在 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 中,这根本不是问题......
最佳答案
您在这里模拟一个具体的对象。起订量与接口(interface)一起使用时效果最佳。尝试mock roles, not objects (pdf)。例如,引入IObjectRegistry
这样的接口(interface)。目前,您的代码知道它正在处理 ObjectRegistry,理想情况下您应该能够随时切换您的实现。前提是您有适当的抽象。对于可测试性和编程最佳实践来说,“编程到接口(interface)”都是理想的选择。注意这里的接口(interface)并不一定是指C#/Java等方面的接口(interface)。
var registry = new Mock<IObjectRegistry>();
public class ObjectRegistry : IObjectRegistry { // Snip }
那就用这个吧。由于这是一个接口(interface),您可以根据需要自由更改具体(真实/生产)类及其构造函数。您的测试和系统的其余部分应该不知道。如果注册表在接口(interface)上有一个方法,例如 GetObject
,那么您的系统应该简单地依赖于这一抽象,而不是它正在使用 ObjectRegistry
实例这一事实。
当前,您的代码实际上正在创建 ObjectRegistry
的真实实例,然后 stub /模拟有问题的方法。在大多数情况下这并不理想。
关于unit-testing - 使用 Moq,我是否总是需要模拟所有依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15043698/