@ RunWith (MockitoJUnitRunner.class) vs MockitoAnnotations.initMocks (this)

在编写新的 jUnit4测试时,我想知道是使用 @RunWith(MockitoJUnitRunner.class)还是 MockitoAnnotations.initMocks(this)

我创建了一个新的测试 & 向导自动生成一个测试与运行。MockitoJUnitRunner 的 Javadocs 声明如下:

与 JUnit 4.4及更高版本兼容,该运行程序添加了以下行为:

初始化带有 Mock 注释的模拟,因此不需要显式使用 MockitoAnnotations.initMocks (Object)。模拟在每个测试方法之前初始化。 在每个测试方法之后验证框架的使用。

我不清楚使用 Runner 是否比我过去使用的 initMocks()方法有任何优势。

127592 次浏览

使用 Runner 可以节省一点编码(不需要 @Before方法)。另一方面,使用跑步机有时是不可能的,例如,当你已经使用一个,如 SpringJUnit4ClassRunner

就是这样,这只是个人喜好的问题。

MockitoJUnitRunner提供框架使用的自动验证,以及自动的 initMocks()

框架使用的自动验证实际上是值得的。如果你犯了这些错误中的一个,它会给你更好的报告。

  • 您可以调用静态 when方法,但是不要使用匹配的 thenReturnthenThrowthen来完成存根化。(下面代码中的错误1)

  • 您在模拟中调用 verify,但是忘记提供方法调用 您试图验证的

  • doReturndoThrow或 传递一个 mock,但是忘记提供 你在试图阻止。 (下面代码中的错误3)

如果您没有对框架使用进行验证,那么直到对 Mockito 方法的 跟随调用之后,才会报告这些错误。这可能是

  • 在同一测试方法下(如下文错误1) ,
  • 在下一个测试方法中(如下面的错误2) ,
  • 在下一堂测试课上。

如果它们出现在您运行的最后一个测试中(如下面的错误3) ,则根本不会报告它们。

下面是这些类型的错误可能看起来的样子。假设 JUnit 按照这里列出的顺序运行这些测试。

@Test
public void test1() {


// ERROR 1
// This compiles and runs, but it's an invalid use of the framework because
// Mockito is still waiting to find out what it should do when myMethod is called.
// But Mockito can't report it yet, because the call to thenReturn might
// be yet to happen.
when(myMock.method1());


doSomeTestingStuff();


// ERROR 1 is reported on the following line, even though it's not the line with
// the error.
verify(myMock).method2();


}


@Test
public void test2() {


doSomeTestingStuff();


// ERROR 2
// This compiles and runs, but it's an invalid use of the framework because
// Mockito doesn't know what method call to verify.  But Mockito can't report
// it yet, because the call to the method that's being verified might
// be yet to happen.
verify(myMock);
}


@Test
public void test3() {


// ERROR 2 is reported on the following line, even though it's not even in
// the same test as the error.
doReturn("Hello").when(myMock).method1();




// ERROR 3
// This compiles and runs, but it's an invalid use of the framework because
// Mockito doesn't know what method call is being stubbed.  But Mockito can't
// report it yet, because the call to the method that's being stubbed might
// be yet to happen.


doReturn("World").when(myMock);


doSomeTestingStuff();


//  ERROR 3 is never reported, because there are no more Mockito calls.
}

现在,当我五年多前第一次写这个答案的时候,我写道

因此,我建议尽可能使用 MockitoJUnitRunner。然而,正如 TomaszNurkiewicz 正确指出的那样,如果需要另一个 JUnit 运行程序(如 Spring 运行程序) ,则不能使用它。

我的建议已经改变了。自从我第一次写这个答案以来,Mockito 团队已经添加了一个新特性。它是一个 JUnit 规则,执行与 MockitoJUnitRunner完全相同的功能。但这样更好,因为它不排除使用其他运动员。

包括

@Rule
public MockitoRule rule = MockitoJUnit.rule();

在你的测试课上。这将初始化模拟,并自动化框架验证; 就像 MockitoJUnitRunner所做的那样。但是现在,您也可以使用 SpringJUnit4ClassRunner或任何其他 JUnitRunner。从 Mockito 2.1.0开始,还有其他选项可以精确控制报告的问题类型。