【问题标题】:Mockito vs JMockMockito vs JMock
【发布时间】:2014-08-14 18:29:14
【问题描述】:

我正在尝试将我的一些单元测试从使用 JMock 转换为使用 Mockito,并且遇到了一些绊脚石。

首先在我的测试中,当使用 JMock 时,存根的验证和返回是在一个步骤中发生的,如下所示

    contextMockery.checking(new Expectations() {{
        oneOf(dateUtilityService).isBeforeToday(URGENT_DATE);
            will(returnValue(true));
    }});

这实质上验证了该方法是否被调用并同时返回一个固定值。如果未调用 isBeforeToday 方法并同时返回我的固定值 true,则测试失败。而在使用 Mockito 时,我必须验证该方法是否被调用,然后在单独的步骤中返回我的预设值,这些步骤几乎是重复的,如下所示:

    doReturn(true).when(dateUtilityService).isBeforeToday(URGENT_DATE);
    verify(dateUtilityService).isBeforeToday(URGENT_DATE);

有没有办法一步到位?

其次,如果我忘记在我的期望中列出对我的一个模拟的方法调用,JMock 会以“意外调用异常”失败测试,​​在我看来这是正确的,而 Mockito 会很高兴通过测试,除非我明确验证对模拟的方法调用绝不能发生,这是正确的(似乎是错误的)?如果对我模拟出来的依赖项进行了意外的方法调用,有没有办法告诉 mockito 测试失败?

【问题讨论】:

  • 只是出于好奇,您是否也考虑过将测试转换为 JMockit?语法更接近 jMock 的:new Expectations() {{ dateUtilityService.isBeforeToday(URGENT_DATE); result = true; }};

标签: java junit mocking mockito stubbing


【解决方案1】:

1.

当您存根方法调用时,通常不需要验证方法 - 您应该根据返回值检查操作(在您的情况下,可能会发生某些事情,或者当 dateUtilityService 返回 true 时会返回某些内容 - 检查而不是验证与模拟交互。

Mockito 文档也谈到了这一点。 http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#2

2.

这实际上会导致脆弱的测试,不推荐使用 mockito 做事。这就是为什么无法设置此行为的原因。

http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#8

【讨论】:

  • 所以在某些情况下(就像我展示的那样),当存根更改返回类型的值时,这是有道理的。但正如我在问题的第二部分中提到的,如果我忘记在我的测试中存根一个方法调用(可能不会改变任何返回值),我想知道它,以便我可以做出有意识的选择存根调用或告诉测试不应该调用它。
  • @ClintonBosch 您可以在测试方法结束时添加对verifyNoMoreInteractions() 的调用,以检测任何未存根的调用。
  • 自从我开始使用 Mockito(我从 2007 年甚至更早的时候开始使用 JMock ......我不记得了),我注意到绿色测试,同事忘记打电话给合作者,我听到类似“单元测试有时会给您带来误报,最好进行集成测试”。也许,最好使用 JMock 之类的工具,并尝试以另一种方式避免这种“脆弱的测试”,而不是使用 Mockito 之类的弱设计工具。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 2013-02-18
相关资源
最近更新 更多