让EasyMock在重试调用期间引发异常

时间:2018-06-29 13:14:52

标签: spring unit-testing mocking easymock spring-retry

我正在尝试编写一个单元测试,该单元测试在我模拟的RetryTemplate上引发异常。我的断言当前测试失败。

/**
     * Test maybeSendNotification() IOException.
     */
    @Test(expected = RuntimeException.class)
    public void testMaybeSendNotificationIOException() throws IOException
    {
        Instance instance = new Instance();
        instance.setState(new InstanceState().withName("DOWN"));
        instance.setKeyName("prod");

        EasyMock.expect(slackMessageSender.send(EasyMock.isA(HashMap.class))).andThrow(new RuntimeException());

        EasyMock.replay(slackMessageSender);
        assertFalse(instanceService.maybeSendNotification(instance));
        EasyMock.verify(slackMessageSender);
    }

slackMessageSenderretryTemplate都是模拟。

这是被测试的方法:

    boolean maybeSendNotification(Instance newInstance)
        {
            Map<String, String> context = new HashMap<String, String>();
            context.put("message", format("Instance with ID '%s' for load balancer '%s' status is DOWN.",
                    newInstance.getInstanceId(),
                    newInstance.getKeyName()));

            try
            {
                retryTemplate.execute( c -> slackMessageSender.send(context));
                LOG.debug(String.format("Successfully sent Slack notification for instance '%s'.", newInstance.getInstanceId()));
                return true;
            }
            catch(IOException e)
            {
                LOG.debug(String.format("Failed to send Slack notification for instance '%s'.", newInstance.getInstanceId()));
                return false;
}

当前,该方法返回true,但我想让它抛出IOException并返回false。我如何嘲笑这种行为?

2 个答案:

答案 0 :(得分:0)

我不知道重试模板在做什么,但是代码似乎还不错。但是,您似乎想EasyMock.expect(slackMessageSender.send(EasyMock.isA(HashMap.class))).andThrow(new IOException());不行吗?

如果您想在每次重试时都抛出异常,则需要EasyMock.expect(slackMessageSender.send(EasyMock.isA(HashMap.class))).andStubThrow(new IOException());

答案 1 :(得分:0)

正如您所说的retryTemplate也是一个模拟,我假设当前slackMessageSender.send方法从未在测试中执行,因为未调用retryTemplate.execute的回调。 我认为您需要设置retryTemplate模拟来执行其参数。像这样:

EasyMock.expect(retryTemplate.execute).andAnswer(() -> {
    final RetryCallback retryCallback = (RetryCallback) getCurrentArguments()[0];
    return retryCallback.doWithRetry(context);
});
EasyMock.replay(retryTemplate);

还请注意,@Test(expected = RuntimeException.class)EasyMock.verify(slackMessageSender);将永远不会执行,slackMessageSender模拟也不会得到验证,因为抛出异常时代码将退出。

使用jUnit 5,您将可以执行以下操作:

EasyMock.replay(slackMessageSender);
IOException exception = assertThrows(IOException.class, () -> {
    assertFalse(instanceService.maybeSendNotification(instance));
});
EasyMock.verify(slackMessageSender);