spring-boot - JUNIT5 @InjectMocks 抛出 NullPointerException
问题描述
这是我第一个使用 TDD 和 JUNIT 5 的项目。我正在为我的项目使用最新的 Springboot。
我注意到,当我有来自 springboot 的依赖项时,在使用 @InjectMocks 注释时,它们不会在测试阶段被注入。我正在为 authenticationManager 依赖项获取 NullPointerException。但是,当服务方法仅使用使用 springboot JPA 为实体类创建的存储库依赖项时,测试通过。
下面是服务类和对应的测试类。 UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
UserRepository userRepository;
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
UserDetailsService userDetailsService;
@Autowired
JWTUtil jwtUtil;
@Override
@Transactional
public AuthenticationResponseDTO login(AuthenticationRequestDTO authenticationRequestDTO) {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authenticationRequestDTO.getUserName(), authenticationRequestDTO.getPassword()));
UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequestDTO.getUserName());
return new AuthenticationResponseDTO(userDetails.getUsername(), jwtUtil.generateToken(userDetails));
}
catch (BadCredentialsException e) {
throw e;
}
}
UserServiceImplTest.java
@InjectMocks
private UserServiceImpl userServiceImpl;
@Mock
private UserRepository userRepository;
private User userMock;
private AuthenticationRequestDTO authenticationRequestDTO;
@BeforeEach
void init(){
MockitoAnnotations.initMocks(this);
}
@BeforeEach
void setupUser(){
userMock = new User();
userMock.setUserName("sd");
userMock.setPassword("sd");
authenticationRequestDTO = new AuthenticationRequestDTO();
authenticationRequestDTO.setUserName("sd");
authenticationRequestDTO.setPassword("sd");
}
@Test
void testUserIsPresentOrNot(){
Mockito.when( userRepository.findByUserName("sd") ).thenReturn(userMock);
AuthenticationResponseDTO responseDTO = userServiceImpl.login(authenticationRequestDTO);
assertNotNull(responseDTO);
assertEquals(userMock.getUserName(), responseDTO.getName(), "user id should be same.");
}
如果我需要进一步的细节,请告诉我。
解决方案
我不确定我是否 100% 关注,因为我可以看到您缺少一些注释。
如果你想在你需要的单元测试中注入 Spring bean @SpringBootTest/@ExtendWith(SpringExtension.class)
(从我的角度来看它是集成测试)。
如果您想使用 Mockito
@InjectMocks
并@Mock
要求@ExtendWith(MockitoExtension.class)
高于测试类。
并删除以下内容。
@BeforeEach
void init(){
MockitoAnnotations.initMocks(this);
}
从我的角度来看,将依赖注入与 spring 和 Mockito 混合起来太复杂了。我宁愿只使用 Mockito 进行单元测试。
也许下面的文章可以提供帮助。
推荐阅读
- c# - 在 sp_UpdateStockItemAmount 上出现 inteccorect 语法错误
- javascript - 调用signInCallback()时反应应用程序oidc-client IE11问题
- c++ - constexpr 与 lambda 表达式的 C++ 用法
- amazon-web-services - 如何在 AWS 中监控通过我的 VPN 的每个请求?
- javascript - 使用 redux-persist 保留某些属性不起作用
- java - 如何在没有不需要的变量的情况下对实体进行建模以节省内存并减少数据库调用?
- python - Python中多维矩阵的多维索引
- python - 为 Eventlogs 创建 activity_instance
- java - 如何拥有 Springboot JPA 的通用通用存储库
- scala - 类内的对象