首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Mockito中重用模拟行为/最佳实践?

在Mockito中重用模拟行为/最佳实践?
EN

Stack Overflow用户
提问于 2012-10-25 12:32:32
回答 3查看 4.1K关注 0票数 5

我将以以下背景作为开场白:我是一个新手,在测试方面没有太多经验,而且以前从未使用过mocking框架。

我正在为代码编写单元测试,这些代码命中了许多不同的web服务,我曾嘲笑过这些代码。我的许多测试都会验证调用的结果,其中除了对ServiceX的调用之外,所有的服务调用都是成功的。我的第一个直觉是为@Before块中的所有mock设置快乐路径行为,然后修改每个测试的mock行为。

代码语言:javascript
复制
@Before
public void init(){
    when(serviceA.doSomething()).thenReturn(true);
    when(serviceB.doSomething()).thenReturn(true);
    when(serviceC.doSomething()).thenReturn(true);
    when(serviceD.doSomething()).thenReturn(true);
    when(serviceE.doSomething()).thenReturn(true);
}

@Test
public void testDoBusinessSuccess(){
    String result = businessLogic.doBusiness();
    assertThat(result, is("success"));
}

@Test
public void testDoBusinessFailureWhenServiceAFails(){
    when(serviceA.doSomething()).thenReturn(false);

    String result = businessLogic.doBusiness();
    assertThat(result, is("service A is down!"));
}

@Test
public void testDoBusinessFailureWhenServiceBFails(){
    when(serviceB.doSomething()).thenReturn(false);

...

这使得每个测试用例都很简洁,而且很容易看到正在测试的是什么,因为我只指定了偏离规范的行为。

但我怀疑这不是莫基托希望我设置模拟行为的方式,因为当我试图验证ServiceB中的失败意味着serviceC永远不会命中时,我意识到我在@Before中对when(serviceC.doSomething())的调用被算作ServiceC上的调用。也就是说,我的verifyZeroInteractions(serviceC)总是失败,因为我调用了when(serviceC.doSomething()).thenReturn(true),即使测试用例在其他方面从未触及过serviceC。

那么最佳实践是什么呢?在每次测试中显式地为每个mock设置行为是不是更好,即使我会在所有地方重复几乎相同的5行?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-25 12:42:21

代码语言:javascript
复制
when(serviceC.doSomething()) in the @Before counted as invocations on serviceC

我怀疑when构造是否被视为调用,因为这只是存根。

您是否可以仔细检查代码以查看是否从@Test内部调用了serviceC.doSomething

关于最佳实践,我认为您应该只将所有测试用例都常见的存根行为转移到@Before

除了代码的外观之外,我认为您可以尝试将其重构为Chain of Responsibility模式,应该可以帮助您编写测试代码。

票数 2
EN

Stack Overflow用户

发布于 2012-10-25 12:39:15

这并不是专门针对mocking的,但是只有对每个测试都通用的代码才应该放在@ test中,因为它是在每个junit测试之前执行的。

因此,如果您想要特定于测试的行为,那么所有的模拟内容都应该包含在这些测试中。

如果您有多个测试共有的行为,您可以将其提取到一个方法中,该方法仅由那些需要该行为的测试调用。

票数 0
EN

Stack Overflow用户

发布于 2012-10-26 00:36:34

verify正在计数的调用是测试方法本身中的调用。将each方法中的调用更改为如下所示。

代码语言:javascript
复制
doReturn(false).when(serviceA).doSomething();

就存根而言,这与您正在做的事情具有相同的效果;但是为了验证的目的,它不会被算作调用doSomething

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

https://stackoverflow.com/questions/13061581

复制
相关文章

相似问题

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