在模拟上多次调用相同的方法时,Mockito似乎错误地解释了verifyNoMoreInteractions()。在下面的示例中,someInterface.doSomething(param)被多次调用(对于传递的每个参数):
public interface SomeInterface {
int doSomething(int a);
}
public class SomeService {
private final SomeInterface someInterface;
public SomeService(SomeInterface someInterface) {
this.someInterface = someInterface;
}
public int callInterface(int... params) {
int sum = 0;
for (int param : params) {
sum += someInterface.doSomething(param); // call for each param
}
return sum;
}
}测试:
@ExtendWith(MockitoExtension.class)
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); // succeeds???
}
}在上面的例子中,verifyNoMoreInteractions(myInterfaceMock)通过了,尽管verify(myInterfaceMock).doSomething(3)没有被验证。这意味着仍然存在与模拟的交互(即调用myInterface.doSomething(3))。怎么回事?
注意:如果有另一个呼叫告诉SomeInterface.someOtherMethod,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> 发布于 2019-09-01 09:42:47
在分析了这些文档并考虑到来自(@JBNizet)的有用评论后,似乎可以预期从MockitoVersion3.0和JUnit5 (使用Mockito扩展@ExtendWith(MockitoExtension.class))开始的行为。
答案可以在Mockito严格性API的javadoc中找到,在这里我们可以读到:
STRICT_STUBS @孵化公共静态最终严格性STRICT_STUBS 确保测试干净,减少测试代码重复,提高调试能力。提供灵活性和生产力的最佳组合。强烈推荐。计划默认为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 (!)
}莫奇托怎么知道什么叫什么?因为它分析了stubbings。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(myInterfaceMock).doSomething(1)是多余的。
如果需要,可以通过将verify()更改为WARN来自动验证对@MockitoSettings(strictness = Strictness.WARN)的单个调用,这可以由@MockitoSettings(strictness = Strictness.WARN)实现。
以下版本的测试如最初预期的那样失败:
@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)这似乎取决于他/她想要使用的测试的设计者。新的默认严格性- STRICT_STUBS确实减少了编写的测试代码的数量。
https://stackoverflow.com/questions/57744435
复制相似问题