junit 如何在Lambda中抛出单元测试异常?

jtjikinw  于 2022-11-11  发布在  其他
关注(0)|答案(2)|浏览(211)

我有一个方法:

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

suzh9iv8

suzh9iv81#

你不需要这个令人生畏的多行lambda。在lambda表达式外面有if-语句比把它塞在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");
}
h7appiyu

h7appiyu2#

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

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")));

相关问题