I'm trying to write exception handling and tests for said handling in Kotlin, using Mockito. The tests are failing due to the exceptions not being thrown and I can't figure out why. It looks like they should be thrown and I'm stumped.
Here is a sample of the code in question.
private fun tryToDoTheThing(workItem: WorkItem, metrics: Metrics) {
try {
serviceFacade.doTheThing(workItem.accountId, workItem.name)
} catch (ex: Exception) {
handleException(ex, metrics, workItem)
}
}
@Throws(DoTheThingFailedException::class)
private fun handleException(ex: Exception, metrics: Metrics, workItem: WorkItem) {
var message: String
when (ex) {
is <other exception cases that are not valid for this question> -> {
throwTheThingFailedException(message, metrics)
}
is RuntimeException -> {
metrics.addCount(FAULT, 1)
val cause = ex.cause
message = "Received exception when attempting to to the thing " +
"name=[${workItem.name}], accountId=[${workItem.accountId}]"
if (cause is HttpFailureException) {
metrics.addProperty(EXCEPTION, cause!!::class.java.simpleName)
} else {
metrics.addProperty(EXCEPTION, ex::class.java.simpleName)
}
LOG.info(message)
throw DoTheThingFailedException(message, ex)
}
}
}
@Throws(DoTheThingFailedException::class)
private fun throwAcknowledgeJobFailedException(message: String, metrics: Metrics) {
LOG.info(message)
metrics.addCount(ERROR, 1)
throw DoTheThingFailedException(message)
}
And here is the test
@Test(expected = RuntimeException::class)
fun handleRuntimeException() {
// given
val errorMessage = "Received exception when attempting to acknowledge name=[name], accountId=[accountId]"
`when`(serviceFacade.doTheThing(any(), any())).thenThrow(RuntimeException())
// when (this calls the item that does the thing)
val runOneIteration = WorkDispatcher::class.java.getDeclaredMethod("runOneIteration")
runOneIteration.invoke(workDispatcher)
// then
verify(metrics).addCount(FAULT, 1)
verify(metrics).addProperty(EXCEPTION, "RuntimeException")
}
I have also tried variations of throwing the exception in this test, including
whenever(serviceFacade.doTheThing(any(), any())).doAnswer { throw RuntimeException(errorMessage) }
and
whenever(serviceFacade.doTheThing(any(), any())).doThrow(RuntimeException(errorMessage))
Even if I add a println statement that verifies the exception is a runtime exception, after the log message, the exception prints but it still gives me the following result:
[junit] Testcase: handleRuntimeException(com.abc.def.packageName.WorkDispatcherTest): FAILED
[junit] Expected exception: java.lang.RuntimeException
[junit] junit.framework.AssertionFailedError: Expected exception: java.lang.RuntimeException