带有Java 8,lambda表达式和Mockito-Java8附加组件的更紧凑的Mockito

Mockito-Java8是一组Mockito附加组件,它们利用Java 8和lambda表达式使Mockito的模拟更加紧凑。

在2015年初,我进行了简短的演讲, Java 8为测试带来了力量! 我在GeeCON TDD 2015和DevConf.cz 2015上发表了演讲。在我使用4个示例的演讲中,我展示了Java 8(即lambda表达式)如何简化测试工具和总体上的测试。 这些工具之一就是Mokcito。 为了不让我的PoC代码死在幻灯片上并使之简单地供他人使用,我发布了一个小项目,其中有两个在特定情况下非常有用的Mockito Java 8附加组件。

快速介绍

作为前提,我们假设我们具有以下数据结构:

@Immutable
class ShipSearchCriteria {
    int minimumRange;
    int numberOfPhasers;
}

该库提供了两个附加组件:

Lambda匹配器 –允许在lambda表达式中定义匹配器逻辑。

given(ts.findNumberOfShipsInRangeByCriteria(
    argLambda(sc -> sc.getMinimumRange() > 1000))).willReturn(4);

ArgumentCaptor – Java 8版本 –允许在一行中使用ArgumentCaptor (此处与AssertJ一起使用):

verify(ts).findNumberOfShipsInRangeByCriteria(
    assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(2000)));

Lambda匹配器

借助静态方法argLambda将创建一个lambda匹配器实例,该实例可用于在lambda表达式(此处用于存根)中定义匹配器逻辑。 当使用复杂的类作为参数传递时,它可能特别有用。

@Test
public void shouldAllowToUseLambdaInStubbing() {
    //given
    given(ts.findNumberOfShipsInRangeByCriteria(
        argLambda(sc -> sc.getMinimumRange() > 1000))).willReturn(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(1500, 2))).isEqualTo(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(700, 2))).isEqualTo(0);
}

相比之下,使用Java 7中的自定义Answer实现的逻辑相同:

@Test
public void stubbingWithCustomAsnwerShouldBeLonger() {  //old way
    //given
    given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(new Answer<Integer>() {
        @Override
        public Integer answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            ShipSearchCriteria criteria = (ShipSearchCriteria) args[0];
            if (criteria.getMinimumRange() > 1000) {
                return 4;
            } else {
                return 0;
            }
        }
    });
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(1500, 2))).isEqualTo(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(700, 2))).isEqualTo(0);
}

甚至Java 8和可读性较差的构造也无济于事:

@Test
public void stubbingWithCustomAsnwerShouldBeLongerEvenAsLambda() {  //old way
    //given
    given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(invocation -> {
        ShipSearchCriteria criteria = (ShipSearchCriteria) invocation.getArguments()[0];
        return criteria.getMinimumRange() > 1000 ? 4 : 0;
    });
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(1500, 2))).isEqualTo(4);
    //expect
    assertThat(ts.findNumberOfShipsInRangeByCriteria(
        new ShipSearchCriteria(700, 2))).isEqualTo(0);
}

Argument Captor – Java 8版本

静态方法assertArg创建一个参数匹配器,该实现器内部使用ArgumentMatcher并在lambda表达式中提供一个断言。 下面的示例使用AssertJ提供有意义的错误消息,但是可以使用任何断言(例如来自TestNG或JUnit的本地声明)(如果确实需要)。 这允许内联ArgumentCaptor:

@Test
public void shouldAllowToUseAssertionInLambda() {
    //when
    ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
    //then
    verify(ts).findNumberOfShipsInRangeByCriteria(
        assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(2000)));
}

与经典方式的3行相比:

@Test
public void shouldAllowToUseArgumentCaptorInClassicWay() {  //old way
    //when
    ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
    //then
    ArgumentCaptor<ShipSearchCriteria> captor = 
        ArgumentCaptor.forClass(ShipSearchCriteria.class);
    verify(ts).findNumberOfShipsInRangeByCriteria(captor.capture());
    assertThat(captor.getValue().getMinimumRange()).isLessThan(2000);
}

摘要

所呈现的附加组件是作为我的会议演讲的PoC创建的,但是应具有完全的功能,并在特定情况下可能有用。 要在您的项目中使用它,只需使用Mockito 1.10.x或2.0.x-beta,将mockito-java8添加为依赖项,当然可以使用Java 8+编译您的项目。

翻译自: https://www.javacodegeeks.com/2015/07/more-compact-mockito-with-java-8-lambda-expressions-and-mockito-java8-add-ons.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值