java 测试中密码编码器出现问题

tnkciper  于 2022-10-30  发布在  Java
关注(0)|答案(1)|浏览(189)

在尝试测试一个方法时,我在这行代码中得到了一个NullPointerException
第一个
我已经提供了一个WebConfig类的模拟,但是看起来还缺少一些东西。提前感谢你的帮助。
我的代码:
第一个

brccelvz

brccelvz1#

when(webConfig.passwordEncoder().encode(any())).thenReturn(userUpdated.getPassword());

这条线就是问题所在webConfig是一个mock,这意味着它将截取所有方法调用并摘录注册的行为,如果没有,则摘录默认行为。webConfig.passwordEncoder()是对yuor mock的第一个调用,您还没有告诉mock要做什么,因此,它将执行默认的返回null。然后,您可以继续模拟对返回值的encode调用,这将失败。
您应该告诉Mockito在默认情况下执行其他操作(@Mock(answer = Answers.RETURNS_DEEP_STUBS而不是普通的@Mock),或者显式模拟对webConfig.passwordEncoder()的调用,并返回一个模拟的PasswordEncoder,然后模拟encode的行为。
然而,在UserService中注入WebConfig而不是PasswordEncoder的事实才是真正的问题(或者说是设计中的问题),应该注入PasswordEncoder

@Service
public class UserService {

    private final SecurityService securityService;
    private final IUserRepository userRepository;
    private final PasswordEncoder encoder;

    public UserService(SecurityService securityService, IUserRepository userRepository, PasswordEncoder encoder) {
      this.securityService=securityService;
      this.userRepository=userRepository;
      this.encoder=encoder;
    }

    public User updateProfile (UserProfileDTO userProfileDTO) {
        User user = userRepository.findByEmail(securityService.getLoggedUser());
        user.setFirstName(userProfileDTO.getFirstName());
        user.setLastName(userProfileDTO.getLastName());
        user.setEmail(securityService.getLoggedUser());
        if(!userProfileDTO.getConfirmPassword().equals(userProfileDTO.getPassword())){
            throw new PasswordException("Password confirmation not match");
        }
        user.setPassword(encoder.encode(userProfileDTO.getPassword()));
        return userRepository.save(user);
    }
}

现在,您也可以修改测试。

@ExtendWith(MockitoExtension.class)
public class Test {

    @Mock
    SecurityService securityService;

    @Mock
    IUserRepository userRepository;

    @Mock
    PasswordEncoder encoder;

    @InjectMocks
    UserService userService;

    @Test
    public void updateProfileTest() {
        UserProfileDTO userDTO = new UserProfileDTO();
        userDTO.setEmail("john@simons");
        userDTO.setFirstName("John");
        userDTO.setLastName("Simons");
        userDTO.setPassword("pass");
        userDTO.setConfirmPassword("pass");

        User userForUpdate = new User();
        userForUpdate.setFirstName("Joo");
        userForUpdate.setLastName("Sim");
        userForUpdate.setBalance(242.20);
        userForUpdate.setEmail("john@simons");
        userForUpdate.setPassword("pass");
        userForUpdate.setRole("ROLE_USER");

        User userUpdated = new User();
        userUpdated.setFirstName("John");
        userUpdated.setLastName("Simons");
        userUpdated.setBalance(242.20);
        userUpdated.setEmail("john@simons");
        userUpdated.setPassword("pass");
        userUpdated.setRole("ROLE_USER");

        when(userRepository.findByEmail(any())).thenReturn(userForUpdate);
        when(encoder.encode(any())).thenReturn(userUpdated.getPassword());
        when(userRepository.save(any())).thenReturn(userUpdated);

        User test = userService.updateProfile(userDTO);
        assertEquals("john@simons",test.getEmail());
    }
}

现在,您的服务只依赖于它所需要的类,而不需要了解有关配置的一些信息。

相关问题