首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mockito -verifyNoMoreInteractions具有不同参数的多个调用

Mockito -verifyNoMoreInteractions具有不同参数的多个调用
EN

Stack Overflow用户
提问于 2019-09-01 08:34:34
回答 1查看 1.6K关注 0票数 1

在模拟上多次调用相同的方法时,Mockito似乎错误地解释了verifyNoMoreInteractions()。在下面的示例中,someInterface.doSomething(param)被多次调用(对于传递的每个参数):

代码语言:javascript
运行
复制
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;
    }
}

测试:

代码语言:javascript
运行
复制
@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会发出信号,但它似乎没有检测到上述情况。

我的测试用例的依赖关系:

代码语言:javascript
运行
复制
<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>  
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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)打电话就够了。因此,此测试也成功:

代码语言:javascript
运行
复制
@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指出了哪些方法应该被验证,因为这段代码:

代码语言:javascript
运行
复制
    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)实现。

以下版本的测试如最初预期的那样失败:

代码语言:javascript
运行
复制
@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);

    }

}

并附有信息:

代码语言:javascript
运行
复制
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确实减少了编写的测试代码的数量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57744435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档