[英]Using BCryptPasswordEncoder in Unit Test returns a null value
我正在 Spring 启动应用程序上学习 JUnit 和 Mockito 的单元测试,我有一个要测试的注册方法,在我的测试方法中我创建了一个用户,但我看到密码的值始终是 null using.encode (mypassword),导致断言错误。
UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public UserServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@Override
public User register(User user) {
Role role = roleService.findByName(ERole.ROLE_USER);
Set<Role> roleSet = new HashSet<>();
user.setFullName(user.getFullName());
user.setEmailAddress(user.getEmailAddress());
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setConfirmPassword("");
user.setEmailVerified(true);
roleSet.add(role);
user.setRoles(roleSet);
if(userRepository.existsByEmailAddress(user.getEmailAddress())) {
throw new EmailAlreadyExistsException("Account already exists with this email");
}
return userRepository.save(user);
}
}
UserServiceImplTest.java
@ExtendWith(MockitoExtension.class)
class UserServiceImplTest {
@InjectMocks
private UserServiceImpl userService;
@Mock
private UserRepository userRepository;
@Mock
public PasswordEncoder passwordEncoder;
@BeforeEach
void setUp() {
userService = new UserServiceImpl(userRepository, passwordEncoder);
}
@Test
void testIfUserCanRegisterSuccessfully() {
User user = new User(1, "admin", "admin@gmail.com", passwordEncoder.encode("password"));
when(userRepository.save(any())).thenReturn(user);
User theUser = userService.register(user);
System.out.println("theUser: " + theUser);
assertNotNull(theUser);
assertEquals(1, theUser.getId());
assertEquals("admin@gmail.com", theUser.getEmailAddress());
assertTrue(passwordEncoder.matches("password", theUser.getPassword()));
}
}
安全配置.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${spring.security.ant.matchers}")
private String[] securityAntMatchers;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint authenticationEntryPoint;
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
return new JwtAuthenticationTokenFilter();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable().formLogin().disable().httpBasic().disable();
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.and()
.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http
.authorizeRequests()
.antMatchers(securityAntMatchers)
.permitAll()
.anyRequest()
.authenticated();
}
}
theUser的output是这个,测试方法时不知道密码加密怎么处理。
theUser: User{id=1, fullName='admin', emailAddress='admin@gmail.com', dateJoined=Tue Nov 15 00:06:01 CAT 2022, emailVerified=true, password='null'}
已编辑
@BeforeEach
void setUp() {
// Instantiating password encoder before every test, now I get the output
this.passwordEncoder = new BCryptPasswordEncoder();
userService = new UserServiceImpl(userRepository, passwordEncoder);
}
@Test
void testIfUserCanRegisterSuccessfully() {
User user = new User(1, "admin", "admin@gmail.com","password");
when(userRepository.save(any())).thenReturn(user);
User created = userService.register(user);
assertEquals(created.getPassword(), user.getPassword());
assertEquals(created.getEmailAddress(), user.getEmailAddress());
verify(userRepository).save(any());
}
您在测试中的服务:
@Mock
private UserRepository userRepository;
@Mock
public PasswordEncoder passwordEncoder;
是模拟,这意味着它们实际上不会做任何事情,除非您通过存根方法明确告诉它们要做什么,就像您在这里所做的那样:
when(userRepository.save(any())).thenReturn(user);
问题是您没有在passwordEncoder
中添加任何方法,因此它的方法将不执行任何操作并返回null
。
此外,您似乎正在对密码进行两次编码(一次在测试中,一次在register
方法中),即使使用适当的存根,这也可能导致错误
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.