模拟无效方法的try catch块并使用EasyMock或Mockito捕获异常

问题描述 投票:0回答:1

我有类似这样的代码,我想完全在下面的代码中编写单元测试。我可以尝试尝试部分代码,但无法弄清楚如何测试catch异常部分。

public class CacheUpdateTask implements Runnable {

    private WarehouseCache cache;

    private static final int EXPONENTIAL_MULTIPLIER = 100;

    private static final int MAXIMUM_TIME_LIMIT = 5;

    public CacheUpdateTask(
            final WarehouseCache cache) {
        this.cache = cache;
    }

    @Override
    public void run() {
        LOG.info("Requesting warehouse mapping from AService and updating the cache.");
        final Callable<Void> updateCache =
                new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        cache.updateWarehouseCountryCodeCache();
                        return null;
                    }
                };
        final Retryer<Void> retryer = RetryerBuilder.<Void>newBuilder()
                .retryIfException()
                .withWaitStrategy(WaitStrategies.exponentialWait(EXPONENTIAL_MULTIPLIER, MAXIMUM_TIME_LIMIT,
                        TimeUnit.MINUTES))
                .withStopStrategy(StopStrategies.neverStop())
                .build();
        try {
            retryer.call(updateCache);
        } catch (ExecutionException | RetryException e) {
            e.printStackTrace();
            LOG.error(e);
            LOG.error("Exception when refreshing the cache.");
        }
        LOG.info("Cache has been updated.");
    }
}

注意事项

  • 此处重试器配置为neverStop。每当调用retryer.call(updateCache);引发异常时,重试器实际上就会重试。因此,在try块中,当retryer.call(updateCache)引发异常时,执行不会流到捕获块,而只会继续尝试。
  • 我试图模仿try块中的代码以多种方式引发某些异常,但是它从来没有在catch中调用代码。下面的代码是我在创建此问题之前的最后尝试。在我的大多数尝试中,测试都成功了,但我从未结束对catch块的测试
  • 以下代码成功运行,但根据代码覆盖率测试,它实际上未达到catch block
@Test (expected = ExecutionException.class)
    public void test_UpdateCacheFOServiceRunException() throws Exception {
        WarehouseCacheFOServiceUpdateTask mockUpdateTaskFOService;
        WarehouseCache mockClientCache;
        mockUpdateTaskFOService = Mockito.mock(WarehouseCacheFOServiceUpdateTask.class);
        mockClientCache = Mockito.mock(WarehouseCache.class);


        Mockito.doThrow(ExecutionException.class)
                .when(mockClientCache).updateWarehouseCountryCodeCacheFOService();
        //clientCache.updateWarehouseCountryCodeCacheFOService();
        //Mockito.doThrow( ExecutionException.class )
          //      .when(mockUpdateTaskFOService).run();
        mockClientCache.updateWarehouseCountryCodeCacheFOService();
        mockUpdateTaskFOService.run();

    }

java junit mocking mockito easymock
1个回答
0
投票

您的测试不正确,期望如此

@Test(expected = ExecutionException.class)

如果回头看代码,将会看到捕获,记录并吞下了该异常。它永远不会被抛弃,因此您的测试不应期望它。

除此之外,您的测试看起来大致正确。由于记录器是静态的,因此您无法进行任何有意义的断言。

以下内容有些误导

Mockito.doThrow(ExecutionException.class)

由于ExecutionException,您正在尝试捕获一个异常,而Retryer应该用来包装原始异常。您当前正在模拟的是ExecutionException包装了ExecutionException。为了您的测试,它将起作用,但是不现实。我会抛出一个通用的Exception.class(然后将其包装)。


您的代码中有一个小错误,将导致误导性日志记录。即使抛出,捕获和记录异常,该行也将执行。

LOG.info("Cache has been updated.");

您有两种选择,您可以将return放入捕获中,或移动记录行。

try {
    retryer.call(updateCache);
    LOG.info("Cache has been updated."); // this
} catch (ExecutionException | RetryException e) {
    e.printStackTrace();
    LOG.error(e);
    LOG.error("Exception when refreshing the cache.");
    return; // or this
}
© www.soinside.com 2019 - 2024. All rights reserved.