I have a service class MyService with following method
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);
}
My existing tests are passing and providing coverage for this method in all except for the catch block.
I would like to unit test this method using JUnit5, Mockito in order to get the coverage of the catch block but I dont know how to make a unit test that will provide coverage for the above catch block.
I have tried few things and most I can do is this:
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");
}
However, while the above test will pass, it will not provide coverage for the catch block in unlockFailed()
method.