簡體   English   中英

在單元測試中使用 BCryptPasswordEncoder 返回 null 值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM