I have a spring service (MyService) that uses a mapstruct mapper (CustomMapstructMapper) :
@Service
public class MyService {
private final ClassA classA;
private final ClassB classB;
/*
other private fields declarations...
*/
private CustomMapstructMapper customMapstructMapper = Mappers.getMapper(CustomMapstructMapper.class);
//MyService constructor
public MyService(final ClassA classA, etc...) {
this.classA = classA;
//etc...
}
public ServiceOutput mainMethod(some parameters) {
//some business logic
MyMapperOutput myMapperOutput = customMapstructMapper.map(MapperParameter parameter);
ServiceOutput serviceOutput = some business logic with myMapperOutput;
return serviceOutput;
}
}
I want to unit test MyService (I am using Junit 5) and mock my CustomMapstructMapper output without calling the real mapper during the test execution. I already have another test class that specificly test all the custom mappings in CustomMapstructMapper.
So I have this test class :
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
@InjectMocks
private MyService myService;
@Mock
private CustomMapstructMapper customMapstructMapper;
@Mock
private MyMapperOutput myMapperOutput;
@Test
void testMyService() {
/*
Some mocks creation ..
*/
Mockito.when(myMapperOutput.getSomeField()).thenReturn("Some value");
Mockito.when(customMapstructMapper.map(Mockito.any(MapperParameter.class))).thenReturn(myMapperOutput);
ServiceOutput serviceOutput = myService.mainMethod(some parameters);
/*
Some assertions on serviceOutput
*/
}
}
When I run my test, the implementation of my mapper customMapstructMapperImpl is called in MyService, not my mock. A NullPointerException is thrown in my mapper because some fields are not initiated. I have tried to create a mock with the implementation of my mapstruct mapper :
@Mock private CustomMapstructMapperImpl customMapstructMapper;
but I get the same result.
What am I doing wrong?