TIL: Mocking Exception Throws
Today I learned how to correctly mock exceptions being thrown when using Mockito.
As I’ve mentioned a few times, I’ve been working on improving our unit tests at work. Recently I did some tests where I needed to simulate specific exceptions being thrown in order to validate the exception handling in a particular method. Rather than spend me time trying to actually cause the exceptions to be hit, I figured it would be much easier to just mock the exceptions being thrown on my own.
Initially when I tackled the issue, I used something like the following, where I used the when.thenThrow
syntax:
|
|
And this actually worked. I was able to get my exceptions throwing correctly and trigger the bits of code that I wanted to. I commit my changes and moved on.
But today I had to come back to the code again for another effort which required me to merge in the tests with some slightly modified code. To my surprise, the tests completely stopped working. Rather than running, I constantly got the following error being returned to me:
|
|
What the heck! It was working just fine before!
After spending some more time actually reading the exception and searching around a bit, I found that the issue is actually caused when you try to throw an exception in a method that doesn’t actually throw that exception. For example, let’s say I have the following code:
|
|
In my case, I was mocking this object to throw an IOException
when the doSomething
method was being called. However, because doSomething
only throws a DummyException
, this was triggering the error to be raised. So doing the mock method I posted up above doesn’t work.
But there’s a way to make it work.
Solution
The answer I found was to use something out of the MockitoBDD package, and use the given.willAnswer
methods:
|
|
While this looks nearly identical to the when.thenThrow
, this will actually allow you to return the specific Exception object when the defined event is hit. It will not care that the exception is not thrown on the called method. And for the sake of getting the scenarios covered, I was totally okay with this.
Here’s what the full test ended up looking like:
|
|
Conclusion
Why did this start happening? My only assumption is that something must have changed in the Exceptions that we had created. If that’s not the case, then I truly don’t know why it was working pre merge and not post. I had confirmed all of the versions were the same, and I didn’t see any changes made to those files… but it’s the only thing that would have made sense.
Hopefully you found this useful and were able to learn something along with me. As always, the code for this post can be found in my gethub repo.
💚 A.B.L.