如何用 mockito 测试这个类?
Posted
技术标签:
【中文标题】如何用 mockito 测试这个类?【英文标题】:How to test this class with mockito? 【发布时间】:2021-03-06 15:22:15 【问题描述】:我使用 JWT 令牌实现了 REST API。用户可以注册新帐户,或使用用户名和密码登录。我有一个名为 AuthController 的类。我需要测试两种方法:登录/注册。我想用 Mockito 来测试这个类。
如何模拟身份验证(令牌)?
@RestController
@RequestMapping(value = "/api/auth")
public class AuthController
private final AuthenticationManager authenticationManager;
private final JwtTokenUtils jwtToken;
private final UserService userService;
private final UserRepository repository;
private final PasswordEncoder encoder;
private final RoleRepository roleRepository;
@Autowired
public AuthController(AuthenticationManager authenticationManager, JwtTokenUtils jwtToken, UserService userService, UserRepository repository, PasswordEncoder encoder, RoleRepository roleRepository)
this.authenticationManager = authenticationManager;
this.jwtToken = jwtToken;
this.userService = userService;
this.repository = repository;
this.encoder = encoder;
this.roleRepository = roleRepository;
方法:/登录
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody AuthDto requestDto)
try
String username = requestDto.getUsername();
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(requestDto.getUsername(), requestDto.getPassword()));
User user=userService.findByUsername(username);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtToken.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
return ResponseEntity.ok(new JwtResponseDto(
jwt,
userDetails.getId(),
userDetails.getUsername(),
userDetails.getEmail(),
roles));
catch (AuthenticationException e)
throw new BadCredentialsException("Invalid username or password");
方法:/signUp
@PostMapping("/signup")
public ResponseEntity<?> registerUser(@RequestBody CustomerDto signUpAuthDto)
if (repository.existsByUsername(signUpAuthDto.getUsername()))
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Username is already taken"));
if (repository.existsByEmail(signUpAuthDto.getEmail()))
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Email is already in use"));
if (signUpAuthDto.getPassword() !=null && !signUpAuthDto.getPassword().equals(signUpAuthDto.getConfirm()))
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: You entered two different passwords. Please try again"));
User user = new User(signUpAuthDto.getUsername(),
signUpAuthDto.getEmail(),
encoder.encode(signUpAuthDto.getPassword()));
encoder.encode(signUpAuthDto.getConfirm());
Set<Role> strRoles = signUpAuthDto.getRole();
Set<Role> roles = new HashSet<>();
if (strRoles == null)
Role userRole = roleRepository.findByName(EnumRole.ROLE_USER)
.orElseThrow(()-> new RuntimeException("Error: Role is not found"));
roles.add(userRole);
else
strRoles.forEach(role ->
if ("admin".equals(role))
Role adminRole = roleRepository.findByName(EnumRole.ROLE_ADMIN)
.orElseThrow(()-> new RuntimeException("Error: Role is not found"));
roles.add(adminRole);
else
Role userRole = roleRepository.findByName(EnumRole.ROLE_USER)
.orElseThrow(()-> new RuntimeException("Error: Role is not found"));
roles.add(userRole);
);
user.setRoles(roles);
repository.save(user);
return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
非常感谢任何帮助!
【问题讨论】:
【参考方案1】:此处模拟身份验证的最佳方法是使用 Spring Security Test 依赖项的 SecurityMockMvcRequestPostProcessors
之一:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
因此,您的 Spring MVC 控制器可以使用 @WebMvcTest
编写测试并获得自动配置的 MockMvc
实例。
通过这种方式,您可以使用模拟的 Servlet 环境测试您的端点,并且可以模拟任何您想要的身份验证或登录用户。
this.mockMvc
.perform(
post("/api/auth/signup")
.contentType(MediaType.APPLICATION_JSON)
.content("YOUR_PAYLOAD")
.with(csrf())
.with(SecurityMockMvcRequestPostProcessors.user("duke"))
)
.andExpect(status().isOk())
更多信息请关注MockMvc guide。
【讨论】:
这太棒了!感谢您提供信息。以上是关于如何用 mockito 测试这个类?的主要内容,如果未能解决你的问题,请参考以下文章