首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mockito一次调用模拟的方法,一次是在吟诵行为时。

Mockito一次调用模拟的方法,一次是在吟诵行为时。
EN

Stack Overflow用户
提问于 2020-07-22 12:30:18
回答 1查看 246关注 0票数 0

我遇到了一个非常奇怪的行为,以防我在测试期间更改模拟行为。我嘲笑一个非常简单的界面:

代码语言:javascript
运行
复制
interface Bar { 
    String string(String str); 
}

@Mock
private Bar bar;

然后,我调用它并计算使用AtomicInteger调用的次数,这是这个最小工作示例的副作用。

代码语言:javascript
运行
复制
@Test
public void test() {

    AtomicInteger atomicInteger = new AtomicInteger(0);

    // Mock with the increment
    Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {    
        log.info("MOCK - waiting (1): {}", invocation.getArguments()[0]);
        atomicInteger.incrementAndGet();
        log.info("MOCK - returning (1)");
        return "BAR_1";
    });
    // Invocation of the increment
    log.info("Result (1): " + bar.string("FOO_1"));                       

    // Passes
    Assertions.assertEquals(1, atomicInteger.get());                      
}
代码语言:javascript
运行
复制
14:18:17.336 [main] INFO com.Foo - MOCK - waiting (1): FOO_1
14:18:17.343 [main] INFO com.Foo - MOCK - returning (1)
14:18:17.349 [main] INFO com.Foo - Result (1): BAR_1

只要使用bar.string("FOO_1")一次明显地调用了该方法,测试就会通过。只要我在执行后添加模拟bar的新行为以不增加AtomicInteger,就会再次调用不应该调用的原始模拟:

代码语言:javascript
运行
复制
@Test
public void test() {

    AtomicInteger atomicInteger = new AtomicInteger(0);

    // Mock with the increment
    Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {
        log.info("MOCK - waiting (1): {}", invocation.getArguments()[0]);
        atomicInteger.incrementAndGet();
        log.info("MOCK - returning (1)");
        return "BAR_1";
    });

    // Invocation with increment
    log.info("Result (1): " + bar.string("FOO_1"));

    /* NEW CODE BLOCK STARTS */

    // Mock without the increment
    Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {    
         log.info("MOCK - returning (2): {}", invocation.getArguments()[0]);
         return "BAR_2";
    });

    // Invocation without the increment
    // The previous lines really changed the mock, but it was called one more times
    log.info("Result (2): " + bar.string("FOO_2"));

    /* NEW CODE BLOCK ENDS */

    // Fails, it is 2
    Assertions.assertEquals(1, atomicInteger.get());                      
}
代码语言:javascript
运行
复制
14:19:31.603 [main] INFO com.Foo - MOCK - waiting (1): FOO_1
14:19:31.612 [main] INFO com.Foo - MOCK - returning (1)
14:19:31.620 [main] INFO com.Foo - Result (1): BAR_1
14:19:31.621 [main] INFO com.Foo - MOCK - waiting (1): 
14:19:31.621 [main] INFO com.Foo - MOCK - returning (1)
14:19:31.623 [main] INFO com.Foo - MOCK - returning (2): FOO_2
14:19:31.624 [main] INFO com.Foo - Result (2): BAR_2

令人惊讶的是,日志显示调用模拟方法时第4行没有参数。

当我在同一个测试N-times中包含更多这段代码时,行为不会改变。测试总是失败,期望增量是2而不是1

代码语言:javascript
运行
复制
Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {
     log.info("MOCK - returning (N): {}", invocation.getArguments()[0]);
     return "BAR_N";
});
log.info("Result (N): " + bar.string("FOO_N"));                       

是什么使Mockito在测试1+期间更改其行为后,精确地调用了带有模拟参数的模拟方法一次?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-22 13:01:21

在remocking操作中调用bar.string(Mockito.anyString())仍然等同于bar.string(String)调用,之前曾对此进行过模拟,以增加AtomicInteger

代码语言:javascript
运行
复制
log.info("Result (1): " + bar.string("FOO_1"));  // Increases to 1

Mockito.when(bar.string(Mockito.anyString())).then(invocation -> {  // Increases to 2

在删除之后,当新的模拟生效时,这个数字不再增加。您应该使用clean mocks来避免编写脆弱或复杂的测试代码。

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

https://stackoverflow.com/questions/63034242

复制
相关文章

相似问题

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