首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >验证用Mockito调用函数的次数有什么意义?

验证用Mockito调用函数的次数有什么意义?
EN

Stack Overflow用户
提问于 2018-09-07 12:09:05
回答 4查看 2.1K关注 0票数 17

据我理解,代码测试是测试结果是否正确,就像计算器一样,我需要编写一个测试用例来验证1+1的结果是否为2。

但是,我读过许多关于验证方法调用次数的测试用例。我对此很困惑。最好的例子就是我刚才在“春天行动”中看到的

代码语言:javascript
复制
public class BraveKnight implements Knight {
    private Quest quest;
    public BraveKnight(Quest quest) { 
        this.quest = quest; 
    }
    public void embarkOnQuest() {
        quest.embark(); 
    }
}

public class BraveKnightTest {
    @Test 
    public void knightShouldEmbarkOnQuest() { 
        Quest mockQuest = mock(Quest.class); 
        BraveKnight knight = new BraveKnight(mockQuest); 
        knight.embarkOnQuest(); 
        verify(mockQuest, times(1)).embark(); 
    }
}

我真的不知道为什么他们需要验证embark()函数被一次调用。您不认为embark()在调用embarkOnQuest()之后一定会被调用吗?或者会发生一些错误,我会注意到日志中的错误消息,它显示了错误行号,这可以帮助我快速找到错误的代码。

那么,像上面这样验证有什么意义呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-09-07 12:31:23

需要做的很简单:验证调用的正确次数。在某些情况下,不应该发生方法调用,而在其他情况下,它们应该或多或少地发生在默认情况下。

考虑以下修改后的embarkOnQuest版本

代码语言:javascript
复制
public void embarkOnQuest() {
    quest.embark(); 
    quest.embarkAgain(); 
}

假设您正在测试quest.embark()的错误用例

代码语言:javascript
复制
@Test 
public void knightShouldEmbarkOnQuest() { 
    Quest mockQuest = mock(Quest.class); 
    Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
    ...
}

在本例中,您希望确保不调用quest.embarkAgain (或调用0次):

代码语言:javascript
复制
verify(mockQuest, times(0)).embarkAgain(); //or verifyZeroInteractions

当然,这是另一个简单的例子。还可以添加许多其他例子:

  • 应该在第一次获取时缓存条目的数据库连接器,您可以进行多次调用,并验证对数据库的连接只调用一次(每个测试查询)。
  • 作为一个在加载(或懒散地)上进行初始化的单例对象,可以测试与初始化相关的调用只进行一次。
票数 9
EN

Stack Overflow用户

发布于 2018-09-07 12:47:56

考虑以下代码:

代码语言:javascript
复制
public void saveFooIfFlagTrue(Foo foo, boolean flag) {
    if (flag) {
        fooRepository.save(foo);
    }
}

如果您不检查调用fooRepository.save()的次数,那么如何知道此方法是否正在执行您希望它执行的任务?

这也适用于其他的无效方法。如果没有返回到方法,因此没有响应来验证,那么检查调用了哪些其他方法是验证方法是否正确的好方法。

票数 6
EN

Stack Overflow用户

发布于 2018-09-07 12:23:49

问得好。你提出了一个很好的观点,当你只检查结果时,嘲笑可能会过于迂回。然而,在某些情况下,这确实会导致更健壮的测试。

例如,如果一个方法需要调用外部API,那么简单地测试结果有几个问题:

  • 网络I/O速度慢。如果您有许多这样的检查,它将减慢您的测试用例。
  • 任何这样的往返都必须依赖于发出请求的代码、API和解释API响应的代码才能正确工作。这是许多单一测试的失败点。
  • 如果发生了一些愚蠢的事情,并且您不小心发出了多个请求,这可能会导致程序的性能问题。

来回答你的分问题:

您不认为embarkOnQuest()调用之后一定会调用that ()吗?

测试也有价值,可以让您重构,而不必担心破坏。这一点现在很明显,是的。6个月后会很明显吗?

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

https://stackoverflow.com/questions/52222264

复制
相关文章

相似问题

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