当我运行一个服务层类单元测试我收到一个恼人的NPE。 这个类使用来自MapStruct,其内部使用其他映射器自动生成的映射器(参见映射器注释的“使用”属性):
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;
}
}
我的单元测试是:
@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
...
}
该NPE由该行提出:
candidateDTO.setUser( userMapper.toDto( candidate.getUser() ) );
在CandidateMapperImpl因为candidateMapperImpl内userMapperImpl实例(变量名userMapper)为空。
当我启动与春天启动的应用程序不会出现这种情况:运行,但只与单元测试
任何意见或建议,将不胜感激。 让我知道如果你需要更多的相关信息或细节,或者如果我错过了一些重要的东西。
谢谢
编辑:
我固定的注释与@Autowired的映射和使用这个类注释的问题:
@SpringBootTest(classes = {CandidateMapperImpl.class, UserMapperImpl.class, UserRolesMapperImpl.class,
CandidateMapper.class, UserMapper.class, UserRolesMapper.class})
要概括:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SubMapperImpl.class, SubMapper.class,
OtherSubMapper.class, OtherSubMapperImpl.class...})
public class ServiceTest {
@Autowired
Mapper mapper;
...
}