How to resolve Unneccessary Stubbing exception

Solution 1:

At first you should check your test logic. Usually there are 3 cases. First, you are mocking the wrong method (you made a typo or someone changed tested code so that mocked method is no longer used). Second, your test is failing before this method is called. Third, your logic falls in wrong if/switch branch somewhere in the code so that mocked method is not called.

If this is the first case you always want to change the mocked method for the one used in the code. With the second and the third it depends. Usually you should just delete this mock if it has no use. But sometimes there are certain cases in parametrized tests, which should take this different path or fail earlier. Then you can split this test into two or more separate ones but that's not always good looking. 3 test methods with possibly 3 arguments providers can make your test look unreadable. In that case for JUnit 4 you silent this exception with either

@RunWith(MockitoJUnitRunner.Silent.class) 

annotation or if you are using rule approach

@Rule
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.LENIENT);

or (the same behaviour)

@Rule
public MockitoRule rule = MockitoJUnit.rule().silent();

For JUnit 5 tests you can silence this exception using this annotation provided in mockito-junit-jupiter package:

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class JUnit5MockitoTest {
}

Solution 2:

Replace @RunWith(MockitoJUnitRunner.class) with @RunWith(MockitoJUnitRunner.Silent.class).

Solution 3:

For me neither the @Rule nor the @RunWith(MockitoJUnitRunner.Silent.class) suggestions worked. It was a legacy project where we upgraded to mockito-core 2.23.0.

We could get rid of the UnnecessaryStubbingException by using:

Mockito.lenient().when(mockedService.getUserById(any())).thenReturn(new User());

instead of:

when(mockedService.getUserById(any())).thenReturn(new User());

Needless to say that you should rather look at the test code, but we needed to get the stuff compiled and the tests running first of all ;)

Solution 4:

Silent is not a solution. You need fix your mock in your test. See official documentation here.

Unnecessary stubs are stubbed method calls that were never realized during test execution (see also MockitoHint), example:

//code under test:
 ...
 String result = translator.translate("one")
 ...

 //test:
 ...
 when(translator.translate("one")).thenReturn("jeden"); // <- stubbing realized during code execution
 when(translator.translate("two")).thenReturn("dwa"); // <- stubbing never realized
 ...

Notice that one of the stubbed methods were never realized in the code under test, during test execution. The stray stubbing might be an oversight of the developer, the artifact of copy-paste or the effect not understanding the test/code. Either way, the developer ends up with unnecessary test code. In order to keep the codebase clean & maintainable it is necessary to remove unnecessary code. Otherwise tests are harder to read and reason about.

To find out more about detecting unused stubbings see MockitoHint.

Solution 5:

 when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line
 verify(dao).doSearchInspections(dto);

The when here configures your mock to do something. However, you donot use this mock in any way anymore after this line (apart from doing a verify). Mockito warns you that the when line therefore is pointless. Perhaps you made a logic error?