I am developing a Spring Boot application. For my regular service class unit tests, I am able to extend my test class with MockitoExtension
, and the mocks are strict, which is what I want.
interface MyDependency {
Integer execute(String param);
}
class MyService {
@Autowired MyDependency myDependency;
Integer execute(String param) {
return myDependency.execute(param);
}
}
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
@Mock
MyDependency myDependency;
@InjectMocks
MyService myService;
@Test
void execute() {
given(myDependency.execute("arg0")).willReturn(4);
myService.execute("arg1"); //will throw exception
}
}
In this case, the an exception gets thrown with the following message (redacted):
org.mockito.exceptions.misusing.PotentialStubbingProblem:
Strict stubbing argument mismatch. Please check:
- this invocation of 'execute' method:
myDependency.execute(arg1);
- has following stubbing(s) with different arguments:
1. myDependency.execute(arg0);
In addition, if the stubbing was never used there would be the following (redacted):
org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at MyServiceTest.execute()
However, when I use @MockBean
in an integration test, then none of the strict behavior is present. Instead, the stubbed method returns null because the stubbing "fails" silently. This is behavior that I do not want. It is much better to fail immediately when unexpected arguments are used.
@SpringBootTest
class MyServiceTest {
@MockBean
MyDependency myDependency;
@Autowired
MyService myService;
@Test
void execute() {
given(myDependency.execute("arg0")).willReturn(4);
myService.execute("arg1"); //will return null
}
}
Is there any workaround for this?