我们正在使用Testng 6.8.8 + Mockito 1.10.19,显然我们不能使用MockitoJUnitRunner
,但验证框架仍然有效!
在这篇thread中,我读到它不应该是这种情况。谁能解释一下?这是因为我们还有@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());
}
} 在这个特定的测试中没有任何失败,但是当我运行套件时,Mockito将告诉我有关匹配器使用不正确的信息。
我也可以这样做:
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)
。
答案 0 :(得分:3)
Matchers work via side-effects and static global state,所以你可以把这个电话分成几部分来看看发生了什么。
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会拆除测试框架,测试将传递 - ,除非您在validateMockitoUsage
方法中调用了@After
,这将完全捕捉到这种情况。< / p>
但是,当你进行两次测试时,它们会像这样叠加:
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
中滥用匹配器而失败。在validateMockitoUsage
消息中使用@After
后,您将获得相应的测试失败。