在编写新的jUnit4测试时,我想知道是否使用 @RunWith(MockitoJUnitRunner.class)或 MockitoAnnotations.initMocks(this)。
我创建了一个新测试&向导自动使用Runner生成测试。 MockitoJUnitRunner的Javadocs声明如下:
与JUnit 4.4及更高版本兼容,此跑步者添加了以下行为:
初始化用Mock注释的模拟,因此不需要明确使用MockitoAnnotations.initMocks(Object)。在每种测试方法之前初始化模拟。 验证每个测试方法后的框架使用情况。
我不清楚使用Runner是否比过去使用的 initMocks()方法有任何优势。
任何想法或链接都将不胜感激!
答案 0 :(得分:114)
MockitoJUnitRunner
为您提供框架使用情况的自动验证,以及自动initMocks()
。
框架使用的自动验证实际上值得拥有。如果您犯了其中一个错误,它会为您提供更好的报告。
您调用静态when
方法,但未使用匹配的thenReturn
,thenThrow
或then
完成存根。 (以下代码中的错误1)
您在模拟上调用verify
,但忘记提供方法调用
您正在尝试验证。 (以下代码中的错误2)
您可以在when
,doReturn
或之后调用doThrow
方法
doAnswer
并传递模拟,但忘记提供方法
你正试图存根。 (以下代码中的错误3)
如果您没有验证框架使用情况,那么在跟随调用Mockito方法之前,不会报告这些错误。这可能是
如果它们出现在您运行的最后一个测试中(如下面的错误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开始,还有其他选项可以准确控制报告的问题类型。
答案 1 :(得分:23)
使用runner可以节省一些编码(不需要@Before
方法)。另一方面,使用跑步者有时是不可能的,即当你已经使用跑步者时,例如SpringJUnit4ClassRunner
。
就是这样。这只是一个偏好的问题。