【问题标题】:Get EasyMock to throw an exception during a Retry call让 EasyMock 在 Retry 调用期间抛出异常
【发布时间】:2018-06-29 13:14:52
【问题描述】:

我正在尝试编写一个单元测试,它在我模拟的 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。如何模拟这种行为?

【问题讨论】:

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


    【解决方案1】:

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

    如果你想在每次重试时抛出一个异常,你会想要EasyMock.expect(slackMessageSender.send(EasyMock.isA(HashMap.class))).andStubThrow(new IOException());

    【讨论】:

      【解决方案2】:

      正如你所说,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);
      

      【讨论】:

        猜你喜欢
        • 2011-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-13
        相关资源
        最近更新 更多