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

Unit testing 使用Moq,我是否总是需要模拟所有依赖项?,unit-testing,dependency-injection,refactoring,mocking,moq,Unit Testing,Dependency Injection,Refactoring,Mocking,Moq,在100多次测试中,我有以下几行: var registry = new Mock<ObjectRegistry>(new List<Assembly>()).Object; 因此,我必须更新所有100个测试用例,以使用以下模拟: var objectRegistry = new Mock<ObjectRegistry>(Mock.Of<AssemblyRegistry>(), Mock.Of<UserPromt>()); var

在100多次测试中,我有以下几行:

var registry = new Mock<ObjectRegistry>(new List<Assembly>()).Object;
因此,我必须更新所有100个测试用例,以使用以下模拟:

var objectRegistry = new Mock<ObjectRegistry>(Mock.Of<AssemblyRegistry>(), Mock.Of<UserPromt>());
var objectRegistry=newmock(Mock.Of(),Mock.Of());
我想要的是所有的依赖都是模拟的,无论我需要什么依赖都是不变的

我可以告诉Moq自动模拟它需要的所有依赖项吗


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

您在这里模拟的是一个具体的对象。Moq与接口一起使用时效果最佳。请尝试下载(pdf)。例如,引入一个接口,如
IObjectRegistry
。目前,您的代码知道它正在处理ObjectRegistry,而理想情况下,您应该能够随时切换实现。假设您有一个适当的抽象。对于可测试性和编程最佳实践而言,最好改为“编程到接口”。注意这里的接口并不一定意味着C#/Java等方面的接口

var registry = new Mock<IObjectRegistry>();

public class ObjectRegistry : IObjectRegistry { // Snip }
var registry=newmock();
公共类ObjectRegistry:IObjectRegistry{//Snip}
然后用这个。由于这是一个接口,您可以根据需要自由更改具体(real/production)类及其构造函数。您的测试和系统的其他部分应该不知道。如果注册表在接口上有一个方法,比如
GetObject
,那么系统应该只依赖于这个抽象,而不是它正在使用
ObjectRegistry
实例


当前,您的代码实际上是在创建一个
ObjectRegistry
的真实实例,然后存根/模拟有问题的方法。这在大多数情况下并不理想。

您在这里模拟的是一个具体的对象。Moq与接口一起使用时效果最佳。请尝试下载(pdf)。例如,引入一个接口,如
IObjectRegistry
。目前,您的代码知道它正在处理ObjectRegistry,而理想情况下,您应该能够随时切换实现。假设您有一个适当的抽象。对于可测试性和编程最佳实践而言,最好改为“编程到接口”。注意这里的接口并不一定意味着C#/Java等方面的接口

var registry = new Mock<IObjectRegistry>();

public class ObjectRegistry : IObjectRegistry { // Snip }
var registry=newmock();
公共类ObjectRegistry:IObjectRegistry{//Snip}
然后用这个。由于这是一个接口,您可以根据需要自由更改具体(real/production)类及其构造函数。您的测试和系统的其他部分应该不知道。如果注册表在接口上有一个方法,比如
GetObject
,那么系统应该只依赖于这个抽象,而不是它正在使用
ObjectRegistry
实例


当前,您的代码实际上是在创建一个
ObjectRegistry
的真实实例,然后存根/模拟有问题的方法。这在大多数情况下并不理想。

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


公共对象注册表(IAssemblyRegistry程序集,IUserPromt userPromt)
解决问题的最佳实践是使用接口而不是具体类,并通过这些接口传递依赖项


public ObjectRegistry(IAssemblyRegistry程序集,IUserPromt userPromt)

为什么它们在一百行测试中?在
设置中不可能有这种情况吗
?对测试应用与代码相同的代码气味检测,DRY。如果你发现自己在重复同样的代码,就重构成一个方法。我发现,在很多情况下,mock已经在安装中了。。。所以你是对的,这已经有帮助了。为什么他们要在100行测试中?在
设置中不可能有这种情况吗
?对测试应用与代码相同的代码气味检测,DRY。如果你发现自己在重复同样的代码,就重构成一个方法。我发现,在很多情况下,mock已经在安装中了。。。所以你是对的,这已经有所帮助。在单元测试中使用依赖注入不是一个好主意。应模拟测试系统的所有依赖项。如果你在单元测试中使用DI,你实际上是在创建集成测试。是的,我自己在测试中使用DI的经历很糟糕。但是如果你为每一个测试建立一个新的容器,它就会运行得很好如果不需要的话,我也不会这么做。我不认为用全新的接口层污染干净的代码有什么意义。人们似乎喜欢接口,但使用接口是有原因的,测试兼容性不应该是原因。@Tarion对接口编程是“一件好事”。您可以切换依赖项以使可测试性更容易,这是一个额外的事实。@WouterdeKort您似乎对DI实际上是什么感到困惑。在单元测试中使用DI/IOC容器是一件坏事是的,但是DI(通过构造函数/方法传递类依赖项的行为)是正确的做法。在单元测试中使用依赖项注入不是一个好主意。应模拟测试系统的所有依赖项。如果你在单元测试中使用DI,你实际上是在创建集成测试。是的,我自己在测试中使用DI的经历很糟糕。但是如果你为每一个测试建立一个新的容器,它就会运行得很好如果不需要的话,我也不会这么做。我不认为用全新的接口层污染干净的代码有什么意义。人们似乎喜欢接口,但使用接口是有原因的,测试兼容性不应该是原因。@Tarion对接口编程是“一件好事”。您可以切换依赖项以使可测试性更容易,这是一个额外的事实。@WouterdeKort您似乎对DI实际上是什么感到困惑。在单元测试中使用DI/IOC容器是一件坏事是的,但是DI(传递类的行为