I have a void method that does some tasks trying to test exception scenarios but the test case is getting failed.
public void completetask(){
try{
RemoteUser rm = usrRepo.findById(12);
assistenRepo.save(rm);
}catch(Exception e){
log.error("Exception occurred while making changes {}", e,getMessage());
}
}
How can we test the exception scenario here on JUnit 5?
I have tried this but it's not working
@Test
public void completetaskTest(){
RemoteUser rm = getDummyRemoteUsr();
Mockito.when(usrRepo.findById(12)).thenReturn(rm);
Mockito.when(assistenRepo.save(rm)).thenThrow(new Exception("Error Abnormal"));
Exception exception = Assestions.assertThrow(Exception.class, () -> usrService.completetask());
String expectedMessage = "Exception occurred while making changes";
String actualMessage = exception.getMessage();
Assertions.assetTrue(actualMessage.contains(expectedMessage));
}
I am getting an error for this test case - the check exception is invalid for this method Invalid java.lang.Exception : Error
Can I know what wrong I am doing here ?
CodePudding user response:
You are expecting your method to thrown an exception but in your code, you're handling and logging the exception and no exception is thrown:
public void completetask(){
try {
RemoteUser rm = usrRepo.findById(12);
assistenRepo.save(rm); // <-- Exception is thrown...
} catch(Exception e){ // <-- Catched here
log.error("Exception occurred while making changes {}", e,getMessage());
}
// <-- Method finishes normally.
}
You should be seeing the following in the output:
Exception occurred while making changes Error Abnormal
But your test will be failing here:
Exception exception = Assestions.assertThrow(Exception.class, () -> usrService.completetask());
Because the exception was never thrown. If you comment out the exception handling try / catch
it will pass that point but now it will fail comparing the error messages.
EDIT:
I know this scenario but the problem here is how to solve this issue? How can we write test scenario for this condition –
If you want to verify your exception was handled just remove verification:
@Test
public void completetaskTest(){
RemoteUser rm = getDummyRemoteUsr();
when(usrRepo.findById(12)).thenReturn(rm);
when(assistenRepo.save(rm)).thenThrow(new Exception("Error Abnormal"));
assertTrue(true); // if we reached this line, in means the error has handled.
}
If you really want to go further and check if the message matches (which it might be overkill) you can check the logger, but again, I would't recommend it.
Something like this:
@Auto
Logger log;
...
@Test
public void completetaskTest(){
RemoteUser rm = getDummyRemoteUsr();
when(usrRepo.findById(12)).thenReturn(rm);
when(assistenRepo.save(rm)).thenThrow(new Exception("Error Abnormal"));
// Verify the `log.error` was invoked with exactly those parameters
verify(log, times(1)).error("Exception occurred while making changes {}", "Error Abnormal");
}
That means the exception was thrown, cached and the logger was invoked.
CodePudding user response:
You are not throwing your error, you are just writing a log with one log line.
catch(Exception e){
log.error("Exception occurred while making changes {}", e,getMessage());
}
Here is the javadoc on Assertions.assertThrows
:
Assert that execution of the supplied executable throws an exception of the expectedType and return the exception. If no exception is thrown, or if an exception of a different type is thrown, this method will fail. If you do not want to perform additional checks on the exception instance, ignore the return value.
That's why your assertThrows
method will fail under all circumstances.
So either throw an error in your method you want to test, or check the log print in exceptions for testing.