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
