Java Mockito-verifyNoMoreInteractions-具有不同参数的多个调用
在mock上多次调用同一方法时,Mockito似乎错误地解释了Java Mockito-verifyNoMoreInteractions-具有不同参数的多个调用,java,unit-testing,mockito,Java,Unit Testing,Mockito,在mock上多次调用同一方法时,Mockito似乎错误地解释了verifyNoMoreInteractions()。在下面的示例中,someInterface.doSomething(param)被多次调用(对于传递的每个参数): 测试: 在上述示例中,verifyNoMoreInteractions(myInterfaceMock)通过了验证(myInterfaceMock)。doSomething(3)未验证。这意味着仍然存在与mock的交互(即调用myInterface.doSomethi
verifyNoMoreInteractions()
。在下面的示例中,someInterface.doSomething(param)
被多次调用(对于传递的每个参数):
测试:
在上述示例中,verifyNoMoreInteractions(myInterfaceMock)
通过了验证(myInterfaceMock)。doSomething(3)未验证。这意味着仍然存在与mock的交互(即调用myInterface.doSomething(3)
)。怎么回事
注意:如果有另一个调用,则对SomeInterface.SomeOther方法(而非verifyNoMoreInteractions)发出此信号,但它似乎无法检测到上述情况
情况
我的测试用例的依赖项:
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
org.mockito
莫基托磁芯
3.0.0
测试
org.mockito
莫基托朱庇特酒店
3.0.0
测试
org.junit.jupiter
JUnitJupiter api
释放
测试
在分析文档并考虑(@JBNizet)的有用评论后,从Mockito版本3.0和JUnit5(使用Mockito扩展@extendedwith(MockitoExtension.class)
开始,这似乎是预期的行为
答案可以在javadoc中找到,我们可以阅读:
严格的存根
@孵化公众静态最终严格
确保干净的测试,减少测试代码重复,提高
可调试性。提供灵活性和灵活性的最佳组合
生产率强烈推荐。计划作为Mockito v3的默认值
如果使用Mockito.verifyNoMoreInteractions(对象…),则不再需要
显式验证存根调用。它们是自动验证的
给你
因此,存根方法调用将自动验证
这是什么意思?如果我们举一个有问题的例子,编写测试时完全忽略对verify(myInterfaceMock).doSomething(x)
的调用就足够了。只需将调用留给verifyNoMoreInteractions(myInterfaceMock)
就足够了。因此,该测试也成功:
@Test
public void myTest() {
SomeInterface myInterfaceMock = mock(SomeInterface.class);
SomeService myService = new SomeService(myInterfaceMock);
doReturn(1).when(myInterfaceMock).doSomething(1);
doReturn(2).when(myInterfaceMock).doSomething(2);
doReturn(3).when(myInterfaceMock).doSomething(3);
int sum = myService.callInterface(1, 2, 3);
assertEquals(1 + 2 + 3, sum);
verifyNoMoreInteractions(myInterfaceMock); // NOTE: no individual verify(myInterfaceMock) calls (!)
}
莫基托怎么知道这叫什么?因为它分析存根。Mockito根据以下代码确定应验证哪些方法:
doReturn(1).when(myInterfaceMock).doSomething(1);
doReturn(2).when(myInterfaceMock).doSomething(2);
doReturn(3).when(myInterfaceMock).doSomething(3);
Mockito似乎在说“嘿,伙计,你期望myInterfaceMock
调用doSomething(1)
,所以如果你调用verifyNoMoreInteractions()
我会验证doSomething(1)
是否真的被调用了……所以个人期望verify(1)
是多余的
如果需要,可以通过将严格性更改为警告来启用对验证()
的单独调用的自动验证,这可以通过@MockitoSettings(严格性=严格性.警告)
以下版本的测试如最初预期的那样失败:
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.WARN)
class SomeServiceTest {
@Test
public void myTest() {
SomeInterface myInterfaceMock = mock(SomeInterface.class);
SomeService myService = new SomeService(myInterfaceMock);
doReturn(1).when(myInterfaceMock).doSomething(1);
doReturn(2).when(myInterfaceMock).doSomething(2);
doReturn(3).when(myInterfaceMock).doSomething(3);
int sum = myService.callInterface(1, 2, 3);
assertEquals(1 + 2 + 3, sum);
verify(myInterfaceMock).doSomething(1);
verify(myInterfaceMock).doSomething(2);
verifyNoMoreInteractions(myInterfaceMock);
}
}
留言:
org.mockito.exceptions.verification.NoInteractionsWanted:
No interactions wanted here:
-> at SomeServiceTest.myTest(SomeServiceTest.java:30)
But found this interaction on mock 'someInterface':
-> at SomeService.callInterface(SomeService.java:13)
***
For your reference, here is the list of all invocations ([?] - means unverified).
1. -> at SomeService.callInterface(SomeService.java:13)
2. -> at SomeService.callInterface(SomeService.java:13)
3. [?]-> at SomeService.callInterface(SomeService.java:13)
这似乎取决于测试的设计者,他/她希望使用哪种严格程度。新的默认严格程度-严格程度-在分析文档并考虑(@JBNizet)的有用评论后,肯定会减少编写的测试代码量从Mockito版本3.0和JUnit5(使用Mockito扩展@extendedwith(MockitoExtension.class)
)开始,这似乎是预期的行为
答案可以在javadoc中找到,我们可以阅读:
严格的存根
@孵化公众静态最终严格
确保干净的测试,减少测试代码重复,提高
可调试性。提供灵活性和灵活性的最佳组合
生产力。强烈推荐。计划作为Mockito v3的默认值
如果使用Mockito.verifyNoMoreInteractions(对象…),则不再需要
显式验证存根调用。它们将自动验证
给你
因此,存根方法调用将自动验证
这意味着什么?如果我们举一个有问题的例子,编写测试时完全忽略对verify(myInterfaceMock).doSomething(x)
的调用就足够了。只需将调用留给verifyNoMoreInteractions(myInterfaceMock)
。因此,该测试也成功了:
@Test
public void myTest() {
SomeInterface myInterfaceMock = mock(SomeInterface.class);
SomeService myService = new SomeService(myInterfaceMock);
doReturn(1).when(myInterfaceMock).doSomething(1);
doReturn(2).when(myInterfaceMock).doSomething(2);
doReturn(3).when(myInterfaceMock).doSomething(3);
int sum = myService.callInterface(1, 2, 3);
assertEquals(1 + 2 + 3, sum);
verifyNoMoreInteractions(myInterfaceMock); // NOTE: no individual verify(myInterfaceMock) calls (!)
}
Mockito如何知道调用了什么?因为它分析存根。Mockito根据以下代码确定应该验证哪些方法:
doReturn(1).when(myInterfaceMock).doSomething(1);
doReturn(2).when(myInterfaceMock).doSomething(2);
doReturn(3).when(myInterfaceMock).doSomething(3);
Mockito似乎在说“嘿,伙计,你希望myInterfaceMock
调用doSomething(1)
,所以如果你调用verifyNoMoreInteractions()
我会验证doSomething(1)
是否真的被调用了。。。所以个人期望验证(myInterfaceMock)。doSomething(1)
是多余的
如果需要,可以通过将严格性更改为警告来启用对验证()
的单独调用的自动验证,这可以通过@MockitoSettings(严格性=严格性.警告)
以下版本的测试如最初预期的那样失败:
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.WARN)
class SomeServiceTest {
@Test
public void myTest() {
SomeInterface myInterfaceMock = mock(SomeInterface.class);
SomeService myService = new SomeService(myInterfaceMock);
doReturn(1).when(myInterfaceMock).doSomething(1);
doReturn(2).when(myInterfaceMock).doSomething(2);
doReturn(3).when(myInterfaceMock).doSomething(3);
int sum = myService.callInterface(1, 2, 3);
assertEquals(1 + 2 + 3, sum);
verify(myInterfaceMock).doSomething(1);
verify(myInterfaceMock).doSomething(2);
verifyNoMoreInteractions(myInterfaceMock);
}
}
留言:
org.mockito.exceptions.verification.NoInteractionsWanted:
No interactions wanted here:
-> at SomeServiceTest.myTest(SomeServiceTest.java:30)
But found this interaction on mock 'someInterface':
-> at SomeService.callInterface(SomeService.java:13)
***
For your reference, here is the list of all invocations ([?] - means unverified).
1. -> at SomeService.callInterface(SomeService.java:13)
2. -> at SomeService.callInterface(SomeService.java:13)
3. [?]-> at SomeService.callInterface(SomeService.java:13)
这似乎取决于他/她想要使用的严格程度的测试设计者。新的默认严格性-严格的存根确实减少了编写的测试代码的数量无法复制。您使用的是哪个版本的Mockito?@JBNizet 3.0.0-请参阅answerI最后的更新,我设法重现了您的问题。奇怪的是,它是由@ExtendWith(MockitoExtension.class)
引起的。如果删除该行(在本例中没有用处),测试将按其应该的方式失败。您应该将其作为bug归档到Mockito项目中。另外,您可以使用MockitoAnnotations.initMocks(this)。为了初始化任何注释,如果