I have a service A. A uses a repository R and a service B. B executes REST calls. R and B are injected through the constructor (as it is recomended) of A. I now want to test a method, where both R and B are invoked. But I only want to mock B, as the test database is filled with a lot of test data and I want to use that. I am not able so far to achive this correct injection with Mockito. Here is my code:
@Service class A {
private final R repo;
private final B service;
@Autowired
public A(R repo, B service) {
this.repo = repo;
this.service = service;
}
public int foo() {
repo.doSomeStuff();
service.doSomeStuff();
...
}
}
@SpringBootTest
@ExtendWith(MockitoExtension.class)
class ATest {
@Autowired A service;
@Mock B mockedService;
@BeforeEach
void setupMocks() {
MockitoAnnotations.openMocks(this);
}
@Test
void testFoo() {
service.foo();
...
}
}
I already played around with different variations of also using @InjectMocks
on ATest.service and also leaving out the @Autowired
. Nothing worked so far. Is it even possible? Do I maybe need to use setter injection in A?
CodePudding user response:
You are making things way too complex. Use @MockBean
and Spring Boot will do the rest. Rewrite your test to the following
@SpringBootTest
class ATest {
@Autowired A service;
@MockBean B mockedService;
@Test
void testFoo() {
service.foo();
...
}
}
That is it, nothing more, nothing less. Spring will now use the mocked dependency and inject it into the service.
For more information on testing with Spring Boot I strongly suggest a read of the Testing section in the reference guide. It also has a whole section on mocking when using Spring Boot and testing.