Mocking a Spy method with Mockito
java, junit, mocking, mockito, unit-testing
Solution
I wouldn't use exceptions to test that, but verifications. And another problem is that you can't use `when()` with methods returning void.
Here's how I would do it:
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
Problem
I am writing a unit test for a `FizzConfigurator` class that looks like: ``` public class FizzConfigurator { public void doFoo(String msg) { doWidget(msg, Config.ALWAYS); } public void doBar(String msg) { doWidget(msg, Config.NEVER); } public void doBuzz(String msg) { doWidget(msg, Config.SOMETIMES); } public void doWidget(String msg, Config cfg) { // Does a bunch of stuff and hits a database. } } ``` I'd like to write a simple unit test that stubs the `doWidget(String,Config)` method (so that it doesn't actually fire and hit the database), but that allows me to verify that calling `doBuzz(String)` ends up executing `doWidget`. Mockito seems like the right tool for the job here. ``` public class FizzConfiguratorTest { @Test public void callingDoBuzzAlsoCallsDoWidget() { FizzConfigurator fixture = Mockito.spy(new FizzConfigurator()); Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)). thenThrow(new RuntimeException()); try { fixture.doBuzz("This should throw."); // We should never get here. Calling doBuzz should invoke our // stubbed doWidget, which throws an exception. Assert.fail(); } catch(RuntimeException rte) { return; // Test passed. } } } ``` This seems like a good gameplan (to me at least). But when I actually go to code it up, I get the following compiler error on the 2nd line inside the test method (the `Mockito.when(...)` line: The method when(T) in the type Mockito is not applicable for the arguments (void) I see that Mockito can't mock a method that returns `void`. So I ask: - Am I approaching this test setup correctly? Or is there a better, Mockito-recommended, way of testing that `doBuzz` calls `doWidget` under the hood? And - What can I do about mocking/stubbing `doWidget` as it is the most critical method of my entire `FizzConfigurator` class?