在编写新的 jUnit4 测试时,我想知道是使用 @RunWith(MockitoJUnitRunner.class)
还是 MockitoAnnotations.initMocks(this)
。
我创建了一个新测试,向导自动使用 Runner 生成了一个测试。 MockitoJUnitRunner 的 Javadocs 声明如下:
与 JUnit 4.4 及更高版本兼容,此运行器添加了以下行为:初始化使用 Mock 注释的模拟,因此不需要显式使用 MockitoAnnotations.initMocks(Object)。在每个测试方法之前初始化模拟。在每个测试方法之后验证框架的使用。
我不清楚使用 Runner 是否比我过去使用的 initMocks()
方法有任何优势。
MockitoJUnitRunner
为您提供框架使用的自动验证以及自动 initMocks()
。
框架使用的自动验证实际上是值得拥有的。如果您犯了这些错误之一,它会为您提供更好的报告。
您调用静态 when 方法,但不要使用匹配的 thenReturn、thenThrow 或 then 来完成存根。 (下面代码中的错误1)
您在模拟上调用 verify,但忘记提供您尝试验证的方法调用。 (以下代码中的错误 2)
您在 doReturn、doThrow 或 doAnswer 之后调用 when 方法并传递一个模拟,但忘记提供您尝试存根的方法。 (下面代码中的错误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。但是,正如 Tomasz Nurkiewicz 正确指出的那样,如果您需要另一个 JUnit 运行程序,例如 Spring 运行程序,则不能使用它。
我的建议现在已经改变。自从我第一次写这个答案以来,Mockito 团队添加了一个新功能。这是一个 JUnit 规则,执行与 MockitoJUnitRunner
完全相同的功能。但它更好,因为它不排除使用其他跑步者。
包括
@Rule
public MockitoRule rule = MockitoJUnit.rule();
在你的测试课上。这会初始化模拟,并自动执行框架验证;就像 MockitoJUnitRunner
一样。但是现在,您也可以使用 SpringJUnit4ClassRunner
或任何其他 JUnitRunner。从 Mockito 2.1.0 开始,还有一些额外的选项可以准确控制报告的问题类型。
使用 runner 可以让您节省一点编码(不需要 @Before
方法)。另一方面,有时无法使用跑步者,即当您已经在使用跑步者时,例如 SpringJUnit4ClassRunner
。
而已。这只是一个偏好问题。
@Before
方法包含除 initMocks()
之外的任何内容,那么您必须在迁移到 runner 后保留它。
SpringJUnit4ClassRunner
会自动为我初始化模拟。不过,我不知道普通的春天。
不定期副业成功案例分享
@ExtendWith
编写自己的答案。这不是我真正了解的事情。 Stack Overflow 的伟大之处在于,在这样的问题上,你可以得到多个正确答案。