我有一个使用以下方法的服务类MyService
private LoadingCache<String, Integer> attemptsCache;
public MyService() {
super();
attemptCache = CacheBuilder.newBuilder()
.expireAfterWrite(1, TimeUnits.HOURS)
.build(new CacheLoader<String, Integer>() {
@Override
public Integer load(String key) throws Exception {
return 0
}
});
}
public void unlockFailed(String key) {
int attempts = 0;
try {
attempts = attemptsCache.get(key);
}catch (ExecutionException e) {
attempts = 0; //unit test is not covering this block
}
attempts++;
attemptsCache.put(key, attempts);
}
除了catch块之外,我现有的测试都通过了,并为这个方法提供了覆盖。
我想使用JUnit5、Mockito对此方法进行单元测试,以获得catch块的覆盖率,但我不知道如何进行单元测试,以提供上述catch块的覆盖率。
我试过几种方法,我能做的最多的是:
private final String USER = "fakeuser";
@Spy
@InjectMocks
private UnlockAttemptServiceImpl sut;
@DisplayName("unlockFailed should handle ExecutionException")
@Test()
public void unlockFailed_should_handle_ExecutionException() throws ExecutionException {
// Arrange
LoadingCache<String, Integer> attemptsCache = Mockito.mock(LoadingCache.class);
doThrow(new ExecutionException("Dummy ExecutionException", null)).when(attemptsCache).get(USER);
// Act
sut.unlockFailed(USER);
// Assert
ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
// Act
attemptsCache.get(USER);
});
Mockito.verify(attemptsCache, times(1)).get(USER);
Mockito.verify(sut, times(1)).unlockFailed(USER);
Assertions.assertEquals(exception.getMessage(), "Dummy ExecutionException");
}
但是,虽然上述测试将通过,但它不会为unlockFailed()
方法中的catch块提供覆盖。
1条答案
按热度按时间vcirk6k61#
注入一个工厂来创建您的缓存或将其 Package 在一个定制类中。
工厂
在生产代码中:
在您的测试中:
自定义 Package 类
在生产代码中:
在您的测试中:
但是您也可以直接注入LoadingCache。
the answer to "Why is my class not calling my mocked methods in unit test?"中讨论了类似的解决方案