Junit 模拟依赖类本质上是空的?

Junit 模拟依赖类本质上是空的?,junit,dependency-injection,mockito,Junit,Dependency Injection,Mockito,作为Mockito Junit的初学者,这听起来可能是一个非常垃圾的问题,但我仍然想确认: Class1 input1; @Mock Class2 input2; private Class3 obj; @Before public void setup() { this obj = new Class3(input1, input2); } @Test public void doTest() { val result1 = obj.method1(input1);

作为Mockito Junit的初学者,这听起来可能是一个非常垃圾的问题,但我仍然想确认:

Class1 input1;

@Mock
Class2 input2;

private Class3 obj;

@Before
public void setup() {
    this obj = new Class3(input1, input2);
}

@Test
public void doTest() {
     val result1 = obj.method1(input1); // return sth.
     val result2 = obj.method2(input2); // return null.
}
所以input1和input2被传递到Class3 obj中,但只有input2是模拟依赖项。然后我发现,当我调用依赖于input2的method2时,它只返回null

那么,任何被模拟的类本质上都是空的?这就是为什么我们需要使用when…thenReturn来模拟类?毕竟,我们的目的是测试主要功能,而不是依赖性


我的理解正确吗

是的,你的理解是正确的

如果使用了适当的运行程序(junit4)或扩展名(junit5),模拟对象不为null(即使其
toString
方法可能返回类似
的“null”

但是,可能存在的问题是,您的
Class3#method2
使用了模拟
Class2
的方法,该方法返回null

事实上,这种行为是需要的。在这里,您可以选择:

  • 使用注释
    @mock(answer=Answers.RETURNS\u deep\u stubs)
    使您的模拟返回deep stubs,这样
    Class2的任何方法(不是final,也不是返回原语或包装类型)都将返回模拟,而此模拟的任何方法都将返回模拟,依此类推

  • 明确声明mock应该如何使用以下内容进行操作:
    Mockito.when(input2.myMethod()).thenReturn(“test”)。Mockito提供的subbing API有很好的文档记录:


希望这有帮助,是的,你的理解是正确的

如果使用了适当的运行程序(junit4)或扩展名(junit5),模拟对象不为null(即使其
toString
方法可能返回类似
的“null”

但是,可能存在的问题是,您的
Class3#method2
使用了模拟
Class2
的方法,该方法返回null

事实上,这种行为是需要的。在这里,您可以选择:

  • 使用注释
    @mock(answer=Answers.RETURNS\u deep\u stubs)
    使您的模拟返回deep stubs,这样
    Class2的任何方法(不是final,也不是返回原语或包装类型)都将返回模拟,而此模拟的任何方法都将返回模拟,依此类推

  • 明确声明mock应该如何使用以下内容进行操作:
    Mockito.when(input2.myMethod()).thenReturn(“test”)。Mockito提供的subbing API有很好的文档记录:


希望这有帮助,

模拟类不是空的。它是一个与原始类具有相同签名的框架,但没有实现。它被检测为“查看”所有方法的调用,因此可以在之后进行验证。因此,mock是不起作用的对象。它不能存储数据,也不能执行方法。您只能控制对它的所有调用以及模拟的所有返回值。如果你需要一些更高级的模拟,你应该使用
@Spy
。spy是一个“mock”,但具有原始实现:它是一个检测类,用于检测对它的所有调用并控制输出,但也具有原始存储设施和真实调用

进行实际调用的另一种方法是通过以下构造:
Mockito.when(myMockedObject.thenCallRealMethod()


在单元测试中,最好只测试您正在测试的一个类,而不测试底层类。这听起来像一扇敞开的门,但事实并非如此。您正在测试的类所使用的所有类都应该被模拟。使用mock,您可以完全控制返回值,并且可以测试该类的所有角落情况。所有被模拟的类都应该通过它们自己的单元测试进行测试。这就带来了下一个问题:测试使用的所有类都应该是可注入的或可更改的。您希望能够插入模拟,而不是真正的DB驱动程序,以便查看是否进行了所有正确的调用。

模拟的类不是空的。它是一个与原始类具有相同签名的框架,但没有实现。它被检测为“查看”所有方法的调用,因此可以在之后进行验证。因此,mock是不起作用的对象。它不能存储数据,也不能执行方法。您只能控制对它的所有调用以及模拟的所有返回值。如果你需要一些更高级的模拟,你应该使用
@Spy
。spy是一个“mock”,但具有原始实现:它是一个检测类,用于检测对它的所有调用并控制输出,但也具有原始存储设施和真实调用

进行实际调用的另一种方法是通过以下构造:
Mockito.when(myMockedObject.thenCallRealMethod()

在单元测试中,最好只测试您正在测试的一个类,而不测试底层类。这听起来像一扇敞开的门,但事实并非如此。您正在测试的类所使用的所有类都应该被模拟。使用mock,您可以完全控制返回值,并且可以测试该类的所有角落情况。所有被模拟的类都应该通过它们自己的单元测试进行测试。这就带来了下一个问题:测试使用的所有类都应该是可注入的或可更改的。而不是一个真正的DB驱动程序,你希望能够注入一个模拟,这样你就可以看到是否所有正确的调用