'Creating strict mock when using @MockBean of spring boot?
I use @MockBean
of spring boot (with @RunWith(SpringRunner.class)
) and everything was ok so far.
However the mock provides default implementation for every method of the mocked class so I cannot check if only those methods were called that I expected to be called, i.e. I would like to create strict mock.
Is that possible with @MockBean
?
I don't insist on creating strict mocks if somebody has a good idea how to check if only those methods were called that I expected.
Thanks for the help in advance!
Regards,
V.
Solution 1:[1]
With Mockito you can verify that a method was called:
verify(mockOne).add("one");
or that it was never called (never() is more readable alias for times(0)):
verify(mockOne, never()).remove("two");
Or you can verify that no other method was called:
verify(mockOne).add("one"); // check this one
verifyNoMoreInteractions(mockOne); // and nothing else
For more information see the Mockito documentation.
Solution 2:[2]
You can use Mockito.verify method for mock object which is created by @Mockbean. It can check that how many times it calls, what argument specified, and so on. Please try it.
Solution 3:[3]
Here is one way to do it ( quite involved - it may be better to just wait for Mockito 4 where the default will be strict mocks, or wait until after the test finishes using the mock, and then use verifyNoMoreInteractins )
Replace @MockBean with @Autowired with a test configuration with @Primary
Create a default answer that throws an exception for any unstubbed function
Then override that answer with some stubbing - but you have to use doReturn instead of when thenReturn
// this is the component to mock
@Component
class ExtService {
int f1(String a) {
return 777;
}
}
// this is the test class
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTests {
static class RuntimeExceptionAnswer implements Answer<Object> {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
throw new RuntimeException(
invocation.getMethod().getName() + " was not stubbed with the received arguments");
}
}
@TestConfiguration
public static class TestConfig {
@Bean
@Primary
public ExtService mockExtService() {
ExtService std = Mockito.mock(ExtService.class, new RuntimeExceptionAnswer());
return std;
}
}
// @MockBean ExtService extService;
@Autowired
ExtService extService; // replace mockBean
@Test
public void contextLoads() {
Mockito.doReturn(1).when(extService).f1("abc"); // stubbing has to be in this format
System.out.println(extService.f1("abc")); // returns 1
System.out.println(extService.f1("abcd")); // throws exception
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | hiroyukik |
Solution 3 |