I have a @Component
class that contains some @Inject
components to perform some code logic. In my Test, I would like to execute that logic instead Mock the results. I don't want to import spring-boot-starter-test
because will overload the dependencies and generate conflicts.
The Service1
and Service2
doesn't use any third services, it's has just executed simple logic.
@Component
public class MainService {
@Inject
private Service1 service1;
@Inject
private Service2 service2;
}
---------------- Test Class ----------------
@RunWith(MockitoJUnitRunner.class)
public class SomeTest {
@Mock
private Service1 service1;
@Mock
private Service2 service2;
@InjectMocks
private MainService mainService;
@Before
public void startUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test1() {
Mockito.when(service1.function).thenReturn(...);
Mockito.when(service2.function).thenReturn(...);
// How to provide real execution instead Mock the results?
mainService.start();
// asserts...
}
}
CodePudding user response:
The best approach would be just using the constructor or accessor injection instead of field injection (read more here or here), but if you really need to stick to the field injection, simply replace the @Mock
annotations with @Spy
annotations like so:
@Spy
private Service1 service1;
@Spy
private Service2 service2;
or (if the ServiceX
classes do not have a default constructor):
@Spy
private Service1 service1 = new Service1(...);
@Spy
private Service2 service2 = new Service2(...);
Those fields will be used by Mockito when you call initMocks
and will be injected into the fields annotated with @InjectMocks
. No behavior mocking required, the actual ServiceX
classes code will be called.
I've prepared a fully reproducible code example in a GitHub repository here - the test passes.
CodePudding user response:
If you want to use real instances of service1
and service2
you can use @Spy