Throwing exceptions from Mockito mock
Please could you check that the compiler really is complaining about a RuntimeException
?
The thing about RuntimeException
is that it shouldn't matter at compile time. I suspect the compiler is actually complaining about MyException
- which I presume is a checked exception, noticed by the compiler, which is thrown by the doSomething()
method. You should be able to simply add the throws MyException
to the test method, which will then be caught by the test runner. Since it's expected, the test runner will pass.
DaveyBob
Updated on June 29, 2022Comments
-
DaveyBob almost 2 years
Something tells me I'm doing something wrong...it shouldn't be this hard.
I have a class that relies on some inner class. I'm creating that inner through a protected method so that I can override that in a test to provide a mock. I understand that to get a Mockito mock object to throw an exception from a void method, I have to use doThrow.
But my problem is that the compiler complains that the call to Mockito.doThrow() is throwing RuntimeException...so then I have to add a throws clause to the method setting up the mock. Is that a bug in Mockito itself? doThrow is declaring something that should happen in the future, but not during the setup of the mock.
My OuterClass looks like...
public class OuterClass { protected InnerClass inner; protected void createInner() { inner = new InnerClass(); } protected doSomething() { try { inner.go(); } catch (RuntimeException re) { throw new MyException("computer has caught fire"); } } }
And my test code looks like...
@Test(expected = MyException.class) public void testSomething() { OuterClass outer = new TestOuterClass(); outer.doSomething(); } public static class TestOuterClass extends OuterClass { @Override public void createInner() { InnerClass mock = Mockito.mock(InnerClass.mock); Mockito.doThrow(new RuntimeException("test")).when(mock).go(); // PROBLEM inner = mock; } }
-
DaveyBob about 13 yearsYeah, my mistake. What it's really complaining about is MyException, as you suggested. InnerClass.go() is declared to throw MyException (I left that out in my code above). But OuterClass.createInner() does not. I think it's not the Mockito.doThrow() that's causing the problem...it's the call to .go() on the end that's doing it. So even though @test method already declares throws MyException, this doesn't help.
-
DaveyBob about 13 yearsAh ha! I figured it out. I just need to wrap my doThrow...go() stuff in a try/catch to hide it from the create method. But when the create method is called, it does actually call the mock, and it does get and trap the RuntimeException.