【发布时间】:2022-01-08 19:09:08
【问题描述】:
我正在努力解决一些与 Mockito 和 JUnit 5 与 Spring Boot 应用程序相关的奇怪问题。
这是我的AccountServiceTest 类的片段:
@ExtendWith(MockitoExtension.class)
@Import(MapperConfig.class)
class AccountServiceTest {
@Mock
private AccountRepository accountRepository;
@Mock
private ModelMapper modelMapper;
@Mock
private PasswordEncoder passwordEncoder;
@Mock
private AuthenticationManager authenticationManager;
@Mock
private JwtTokenUtil jwtTokenUtil;
@InjectMocks
private AccountService underTest;
@Test
void itShouldCreateAccountAndAddItToDatabase() {
// given
CreateAccountDto dto = new CreateAccountDto("service.tester@test.com", "service.tester", "12345");
// when
Account account = underTest.create(dto);
Account found = accountRepository.findByUsername(account.getUsername()).orElseThrow();
// then
assertEquals(found, account);
}
...
}
这是我要测试的服务:
@Service
public class AccountService implements FieldValueExists {
@Autowired
private AccountRepository accountRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private ModelMapper modelMapper;
@Autowired
private JwtTokenUtil jwtTokenUtil;
public Account create(CreateAccountDto dto) {
Account account = modelMapper.map(dto, Account.class);
account.setHashedPassword(passwordEncoder.encode(dto.getPassword()));
accountRepository.save(account);
return account;
}
...
}
在控制器中使用时,AccountService 本身似乎一切正常,但在测试单元中,modelMapper.map(...) 方法返回 null 对象,因此它抛出了一个臭名昭著的 NullPointerException。
我还设法将此映射器的配置放在MapperConfig:
@Configuration
public class MapperConfig {
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
/*
Account's related mappings
*/
modelMapper
.typeMap(CreateAccountDto.class, Account.class);
modelMapper
.typeMap(Account.class, AccountDto.class);
modelMapper
.typeMap(Account.class, AuthorDto.class);
/*
Note's related mappings
*/
modelMapper
.typeMap(CreateNoteDto.class, Note.class);
modelMapper
.typeMap(Note.class, NoteDto.class);
modelMapper
.typeMap(EditNoteDto.class, Note.class)
.addMappings(mapper -> {
mapper.when(ctx -> ctx.getSource() != null).map(EditNoteDto::getTitle, Note::setTitle);
mapper.when(ctx -> ctx.getSource() != null).map(EditNoteDto::getContent, Note::setContent);
});
return modelMapper;
}
}
我不知道出了什么问题,因为AccountServiceTest 中的依赖项被正确地模拟了,我想。
【问题讨论】:
-
仅仅注入模拟是不够的,我们还必须配置模拟。我建议阅读关于 mockito 的教程,例如this one from
baeldung.com. -
你的意思是每个模拟都必须定义每个方法在我的测试单元中应该做什么?如果没有,请告诉我应该在 Baeldung 页面上查看什么。
-
全部阅读。学习框架。或者不要使用它。如果我们在不理解框架的情况下使用框架,很可能我们不是在使用而是在滥用它们。
-
目前我只想知道我的主要问题的答案。当我使用 .when().thenReturn() 方法组合时,从之前的文档和您发送的文档中学习,现在它可以正常工作了。它是我的问题的解决方案吗?
标签: java spring-boot junit mockito modelmapper