问题描述
我们正在使用Testng 6.8.8 + Mockito 1.10.19,显然我们不能使用MockitoJUnitRunner
,但是验证框架仍然有效!在此线程中,我读到事实并非如此.有人可以解释吗?这是因为我们还有@Before
*回调和MockitoAnnotations.initMocks(this)
吗?
We are using Testng 6.8.8 + Mockito 1.10.19 and, obviously we can't use MockitoJUnitRunner
, but the validation framework still works!In this thread I read that it should not be the case. Can someone explain? Is this because we still have @Before
* callbacks and 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会告诉我有关不正确使用匹配器的信息.
}Nothing fails in this specific test, but when I run the suite, Mockito will tell me about incorrect use of matchers.
我还可以做类似的事情:
I can also do something like:
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)
的情况.
Don't get me wrong, I really like how it works, but I was surprised to see it without @RunWith(MockitoJUnitRunner.class)
.
推荐答案
匹配器通过副作用和静态全局状态起作用,因此您可以将此次通话分解为多个部分,以了解发生了什么情况.
Matchers work via side-effects and static global state, so you can break this call into pieces to see what's happening.
MockitoAnnotations.initMocks(this);
// in @Before [1]
mealTransformer.transform(any(), any(), any(), any());
// [6] [2] [3] [4] [5]
在初始化[1]之后,Java看到对any
[2-5]的四个调用和对transform
[6]的一个调用.但是,Mockito只看到对any
的四个调用;因为mealTransformer
不是模拟的,所以Mockito无法看到其调用.如果您单独运行该测试,则Mockito会剩下四个未消耗的记录的匹配器. JVM将拆除测试框架,并且测试将通过- ,除非您在@After
方法中对validateMockitoUsage
进行了调用,而这恰恰就是这种情况.
After init [1], Java sees four calls to any
[2-5] and one call to transform
[6]. Mockito, however, only sees the four calls to any
; Because mealTransformer
is not a mock, Mockito can't see its calls. If you ran that test in isolation, Mockito would be left with four recorded matchers that are not consumed. The JVM would tear down the test framework, and the test would pass—unless you have a call to validateMockitoUsage
in an @After
method, which would catch exactly that case.
但是,当您有两个测试时,它们会像这样堆积:
When you have two tests, however, they stack up like this:
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
,您将有适当的测试失败.
Here, step 7 happens in the same test execution in the same JVM as steps 1-6, which means that initMocks
is called when there are 4 unconsumed matchers on the stack. This should never happen, so initMocks
takes its first opportunity to catch that error. One symptom would be if the misused matcher exception corresponds to a matcher outside of the test that fails: testB
failing due to the misuse of a matcher in testA
. With the use of validateMockitoUsage
in an @After
message, you'd have the appropriate test fail instead.
这篇关于Mockito:是否在没有@RunWith(MockitoJUnitRunner.class)的情况下启用了框架用法的验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!