1

I'm receiving an annoying NPE when I run a Unit Test for a service layer class. This class use an autogenerated mapper from MapStruct, which inside use another mapper (see in the Mapper annotation the "uses" attribute):

    Mapper(componentModel = "spring", uses = {UserMapper.class})
public interface CandidateMapper extends EntityMapper<CandidateDTO, Candidate> {



  @Mapping(target = "createdBy", ignore = true)
  @Mapping(target = "createdDate", ignore = true)
  @Mapping(target = "lastModifiedBy", ignore = true)
  @Mapping(target = "lastModifiedDate", ignore = true)
  @Mapping(target = "applications", ignore = true)
  Candidate toEntity(CandidateDTO candidateDTO);

  default Candidate fromId(Long id) {
    if (id == null) {
      return null;
    }
    Candidate candidate = new Candidate();
    candidate.setId(id);
    return candidate;
  }
}

My UnitTest is:

    @RunWith(SpringRunner.class)
    public class CandidateServiceTest {

      private CandidateService candidateService;

      @MockBean
      private UserRepository userRepository;
      @MockBean
      CandidateRepository candidateRepository;
      @MockBean
      UserDetailsService userDetailsService;

      CandidateMapper candidateMapper = Mappers.getMapper(CandidateMapper.class);

      UserMapper userMapper = Mappers.getMapper(UserMapper.class);

      @Before
      public void init() {
      this.candidateService = new CandidateService(candidateRepository,
      candidateMapper, userDetailsService, userMapper);
      }
      @Test
      @WithMockUser(authorities = RolesConstants.ADMIN)
      public void givenUser_whenGetCandidateOrCreateForLogin_create() {
        // Pre-conditions
       ...

        // Mocking data
       ...

        // Given
        given(userRepository.findOneByLogin(eq(login)))
          .willReturn(Optional.of(user));
        given(candidateRepository.findOneByUserLogin(eq(login)))
          .willReturn(Option.of(candidate));

        // When
        CandidateDTO candidateDTO = candidateService.getCandidateOrCreateForLogin(login);

        // Then
       ...
      }

The NPE is raised by this line:

candidateDTO.setUser( userMapper.toDto( candidate.getUser() ) );

in the CandidateMapperImpl because the userMapperImpl instance (variable name userMapper) inside the candidateMapperImpl is null.

This does not happen when I launch the application with spring-boot:run but only with the UnitTest

Any ideas or suggest would be appreciated. Let me know if you'd need more infos or details or if I missed something important.

Thanks

EDIT:

I fixed the issues annotating the Mapper with @Autowired and using this class annotation:

@SpringBootTest(classes = {CandidateMapperImpl.class, UserMapperImpl.class, UserRolesMapperImpl.class,
  CandidateMapper.class, UserMapper.class, UserRolesMapper.class})

To generalize:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SubMapperImpl.class, SubMapper.class, 
OtherSubMapper.class, OtherSubMapperImpl.class...})
public class ServiceTest {

@Autowired
Mapper mapper;

...

}

0 Answers0