如何单元测试Lambda内部抛出的异常?验证错误密码场景
问题:如何测试用户输入错误密码的场景?
待测试的认证方法
public UserEntity authentication(final UserEntity auth) throws AuthenticationException, EmailNotFoundException { final AtomicReference<UserEntity> atomic = new AtomicReference<>(); this.repository .findByEmail(auth.getEmail()) .ifPresentOrElse( usr -> { if (Objects.equals(usr.getPassword(), auth.getPassword())) { atomic.set(usr); } else { throw new AuthenticationException(); } }, () -> { throw new EmailNotFoundException(auth.getEmail()); } ); return atomic.get(); }
成功场景的测试代码
@Test void userAuthentication_success() { given(this.repository.findByEmail(this.user.getEmail())) .willReturn(Optional.of(this.user)); assertThat(this.underTest.authentication(this.user)) .isInstanceOf(UserEntity.class) .isEqualTo(this.user); verify(this.repository) .findByEmail(this.user.getEmail()); }
问题说明
当前尝试测试错误密码场景时无法生效,因为given(this.repository.findByEmail(this.user.getEmail())).willReturn(Optional.of(this.user));会让repository.findByEmail()提前返回结果,不知道如何验证后续密码校验抛出的异常。
解决方案
要测试错误密码场景,你需要构造一个邮箱正确但密码错误的UserEntity对象,然后验证调用认证方法时会抛出AuthenticationException,具体测试代码如下:
@Test void userAuthentication_wrongPassword_throwsAuthenticationException() { // 构造邮箱正确、密码错误的请求对象 UserEntity wrongPasswordUser = new UserEntity(); wrongPasswordUser.setEmail(this.user.getEmail()); wrongPasswordUser.setPassword("wrong_password"); // 设置错误密码 // mock仓库返回正确的用户(邮箱匹配) given(this.repository.findByEmail(wrongPasswordUser.getEmail())) .willReturn(Optional.of(this.user)); // 验证调用认证方法时抛出AuthenticationException AuthenticationException exception = assertThrows(AuthenticationException.class, () -> this.underTest.authentication(wrongPasswordUser)); // 可选:如果需要验证异常信息,可以添加这一步 // assertThat(exception.getMessage()).isEqualTo("对应的异常信息"); // 验证仓库的findByEmail方法被正确调用 verify(this.repository) .findByEmail(wrongPasswordUser.getEmail()); }
关键逻辑说明
- 保持仓库mock的返回值不变(因为邮箱是正确的,能找到用户),这样才能进入密码校验的分支。
- 使用JUnit 5的
assertThrows方法捕获预期的异常,这是验证方法抛出指定异常的标准方式。 - 最后依然要验证仓库方法的调用,确保流程符合预期。
内容的提问来源于stack exchange,提问作者Ivan Ivanchuk
相关产品推荐
相关产品推荐

