我们使用的是TestNG 6.8.8 Mockito 1.10.19,显然我们不能使用MockitoJUnitRunner
,但是验证框架仍然有效!在此线程中,我读到情况并非如此。有人可以解释吗?这是因为我们仍然有@Before
*回调和MockitoAnnotations.initMocks(this)
?
我的代码:
public class MealTransformerTest {
MealTransformer mealTransformer = new MealTransformer();
@Test(expectedExceptions = NotImplementedException.class)
public void shouldThrowException() throws NotImplementedException {
mealTransformer.transform(any(),
any(),
any(),
any());
}
}在这个特定的测试中没有任何失败,但是当我运行套件时,莫科托会告诉我有关匹配器的不正确使用。
我也可以做类似的事情:
public class MealTransformerTest {
MealTransformer mealTransformer = new MealTransformer();
//I don't need it in the tests. But I need at least 1 @Mock or @Spy to trigger framework validation
@Mock
private CloneUtils cloneUtils;
@BeforeMethod
void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test(expectedExceptions = NotImplementedException.class)
public void shouldThrowException() throws NotImplementedException {
mealTransformer.transform(any(),
any(),
any(),
any());
}
@Test(expectedExceptions = NotImplementedException.class)
public void shouldThrowException123() throws NotImplementedException {
mealTransformer.transform(any(),
any(),
any(),
any());
}
}
我收到:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
....
不要误会我的意思,我真的很喜欢它的工作原理,但是没有@RunWith(MockitoJUnitRunner.class)
。
匹配器通过副作用和静态全球状态工作,因此您可以将此调用分为几个,以查看发生了什么。
MockitoAnnotations.initMocks(this);
// in @Before [1]
mealTransformer.transform(any(), any(), any(), any());
// [6] [2] [3] [4] [5]
init [1]之后,Java看到了四个呼叫any
[2-5],一个呼叫transform
[6]。但是,Mockito只看到了any
的四个呼叫;因为mealTransformer
不是模拟,所以Mockito看不到其呼叫。如果您孤立地进行了测试,Mockito将留下四个未消耗的录制的匹配器。JVM会拆除测试框架,测试将通过 - 除非您在@After
方法中呼叫validateMockitoUsage
,这将完全捕获这种情况。
当您有两个测试时,它们会像这样堆叠:
MockitoAnnotations.initMocks(this);
// [1]
mealTransformer.transform(any(), any(), any(), any());
// [6] [2] [3] [4] [5]
// test passes! now the next test
MockitoAnnotations.initMocks(this);
// [7]
mealTransformer.transform(any(), any(), any(), any());
// [12] [8] [9] [10] [11]
在这里,步骤7在与步骤1-6相同的JVM中的同一测试执行中发生,这意味着当堆栈上有4个未消耗的匹配器时,initMocks
被调用。这绝对不会发生,因此initMocks
抓住了第一个机会来捕获该错误。一种症状是,如果滥用的匹配器异常对应于测试外的匹配器 :testB
由于testA
中的匹配器而失败。通过在@After
消息中使用validateMockitoUsage
,您将获得适当的测试失败。