模拟无效方法的try catch块并使用EasyMock或Mockito捕获异常
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟无效方法的try catch块并使用EasyMock或Mockito捕获异常相关的知识,希望对你有一定的参考价值。
我有类似这样的代码,我想完全在下面的代码中编写单元测试。我可以尝试尝试部分代码,但无法弄清楚如何测试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();
答案
您的测试不正确,期望如此
@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
以上是关于模拟无效方法的try catch块并使用EasyMock或Mockito捕获异常的主要内容,如果未能解决你的问题,请参考以下文章
try/catch 在网络图像上不起作用(例外:图像数据无效)