使用`when`作为验证

时间:2016-04-13 05:25:54

标签: java mockito

我有一个实用工具方法,用于数百次测试,以模拟自定义随机数的返回值。这是我的代码的一个(高度人为的)模型:

mockCard(Suit.CLUBS, Face.QUEEN);
Card card = pickACardAnyCard();
assertThat(card.getFace(), is(Face.QUEEN));

然后可以将其用作:

Suit.HEARTS

然而,这使得一些错误有点难以接受。如果测试中的方法错误地要求verify,则模拟返回null并且断言正确失败。但是,通过错误消息告诉传递给模拟的内容是不可能的。

显然,我可以使用mockCard处理此问题。我可以将模拟传递回when函数,然后单独验证是否使用正确的值调用了它。但这确实混淆了测试断言,这些断言与正在测试的内容并不真正相关。每次调用此方法时,我都会指定一个预期的参数值,我更喜欢将断言放在一个地方。请注意,这一切都发生在之前被调用的方法。

理想情况下,我希望when(rand.getCard(suit)).thenReturn(new Card(suit, face)); when(rand.getCard(intThat(not(is(suit))))).thenThrow(new IllegalArgumentException()); 语句在调用异常值时抛出异常。类似的东西:

getCard

这可以在调用ArgumentCaptor时停止测试,这样会更好。但它仍然不允许我展示不正确的论点。

我也尝试使用verify然后检查捕获的值。但很明显,它们适用于when语句而不是verify语句。

是否有标准的Mockito方式,或者我是否需要使用{{1}}语句来混淆我的测试?

1 个答案:

答案 0 :(得分:2)

您可以使用thenAnswer配置模拟答案,例如

private CardRandomiser mockCard(final Suit suit, final Face face) {
    CardRandomiser rand = mock(CardRandomiser.class);

    when(rand.getCard(any(Suit.class))).thenAnswer(new Answer<Card>() {
        @Override
        public Card answer(InvocationOnMock invocation) throws Throwable {
            if(!suit.equals(invocation.getArguments()[0])) {
                 throw new IllegalArgumentException(
                         String.format("Value %s passed, but mocked for %s", invocation.getArguments()[0], suit));
            }
            return new Card(suit, face);
        }
    });

    return rand;
}