Issue
I am trying to mock a function that is called by other function that I am trying to unit test. I am currently using the following code, following the suggestions given here:
@QuarkusTest
public class SampleServiceTest {
@Inject
SampleService sampleService;
@Test
public void testFindById() {
// Given
final Sample sample = SampleDataProvider.createSample();
final SampleResponse expectedResponse = SampleDataProvider.createSampleResponse();
MockedStatic<SampleResponseAssembler> mockedStatic = mockStatic(SampleResponseAssembler.class);
// When
doReturn(sample).when(sampleService).findSampleById(SampleDataProvider.ID);
mockedStatic.when(() -> SampleResponseAssembler.fromSample(sample)).thenReturn(expectedResponse);
final SampleResponse sampleResponse = sampleService.findById(SampleDataProvider.ID);
// Then
verify(sampleService, times(1)).findSampleById(SampleDataProvider.ID);
mockedStatic.verify(() -> SampleResponseAssembler.fromSample(sample), times(1));
assertEquals(expectedResponse, sampleResponse);
}
}
The functions being tested:
public SampleResponse findById(final UUID id) {
LOGGER.debug("findById. id={}", id);
return SampleResponseAssembler.fromSample(findSampleById(id));
}
public Sample findSampleById(final UUID id) {
LOGGER.debug("findSampleById. id={}", id);
final Optional<Sample> optionalSample = sampleRepository.findById(id);
return optionalSample
.orElseThrow(() -> new NotFoundException(NotFoundException.NotFoundErrorMessage.SAMPLE_ID,
id.toString()));
}
I basically want to be able to mock the findSampleById function. I already made this change and it worked properly but "initMocks" is deprecated so I need another solution:
@Spy
@InjectMocks
SampleService sampleService;
@Mock
SampleRepository sampleRepositoryMock;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
}
Solution
Use @ExtendWith(MockitoExtension.class)
instead of @QuarkusTest
.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@ExtendWith(MockitoExtension.class)
class SampleServiceTest {
@Spy
@InjectMocks
SampleService sampleService;
@Mock
SampleRepository sampleRepositoryMock;
@BeforeEach
void setUp() {
// Not needed
}
@Test
void testFindById() {
// ...
}
}
Also, IMO, if we have to mock findSampleById
to test findById
, you should split them into two classes and not use @Spy
. When the code is hard to test it may be the case it needs to be better designed.
Answered By - Edgar Domingues