如何对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()在您开始检查密码之前返回结果。

您不需要这个强大的多行lambda。将if-语句放在lambda表达式之外比将其填充在lambda内部要干净得多。

并且没有必要在AtomicReference中使用复杂逻辑,除非您有意让代码的读者感到困惑。

有三种情况:用户不存在,用户凭据错误,用户数据有效。让我们单独处理它们:

public UserEntity authentication(final UserEntity auth)
throws AuthenticationException, EmailNotFoundException {
UserEntity user = this.repository
.findByEmail(auth.getEmail())
.orElseThrow(() -> new EmailNotFoundException(auth.getEmail()));

if (Objects.equals(user.getPassword(), auth.getPassword())) {
throw new AuthenticationException();
}

return user;
}

要测试异常是否按预期抛出,可以使用assertThrows()的一种风格。

以下是一个测试检查用户凭据不正确时是否会抛出AuthenticationException的示例:

@Test
void userAuthenticationFailure() {
assertThrows(AuthenticationException.class,
() -> this.underTest.authentication(UserWithWorngPassword),
"Wrong user password should trigger an Exception");
}

首先,我会重构您的代码以避免副作用:

public UserEntity authentication(final UserEntity auth)
throws AuthenticationException, EmailNotFoundException {
return this.repository
.findByEmail(auth.getEmail())
.map(usr -> {
if (!Objects.equals(usr.getPassword(), auth.getPassword())) {
throw new AuthenticationException();
}
return usr;
}).orElseThrow(() -> { throw new EmailNotFoundException(auth.getEmail()); });
}

然后,我认为嘲笑this.repository.findByEmail没有问题,我只是认为你让它返回了一个具有正确密码的有效用户。类似于:

given(this.repository.findByEmail(this.user.getEmail())).willReturn(Optional.of(this.user.withPassword("wrong password")));

最新更新