首页 > 解决方案 > 使用 Mockito Junit 测试异常类型

问题描述

大家好,我对 spring-boot 和 Junit Mockito 完全陌生,我正在尝试检查我的方法是否引发了正确的异常 下面是我的服务类中的方法

    public Optional<User> getUserByEmail(String emailaddress) {
    System.out.println("From DB");
    Optional<User> user = userDao.findByEmailAddress(emailaddress);
    user.orElseThrow(() -> new BadRequestException("User Not Found"));
    return user;
}

以下是我的测试方法

    @Test
@DisplayName("TextCase to check if We are able to get Correct User")
public void getUserByEmailExceptionTest() {
    Mockito.when(userDao.findByEmailAddress("mokal006@gmail.com"))
    .thenThrow(UserNotFoundException.class);
     assertThrows(UserNotFoundException.class, () -> {
        LibraryUserDetailsService.getUserByEmail("mokal006@gmail.com");
    });
    
    
}

现在,即使我在实际方法中抛出了错误的异常,这个测试也通过了。

标签: javajunitmockitojunit5

解决方案


要了解为什么您的测试用例通过了错误的异常类型,请检查assertThrows内部工作原理。AssertThrows.java

try {
    // execute lambda expression passed in assertThrows
} catch (Throwable var5) {
    if (expectedType.isInstance(var5)) {
        // if type matches returns the exception back
        return var5; 
    }
    // ..
    // Else throws different exception
    throw new AssertionFailedError(message, var5);
}

JUnit 5 检查异常调用的类型,即使抛出的异常属于父类型Class.isIntance(..),也会返回 true。Class.isInstance(..)在您的情况下,抛出的异常很可能是父类型。

您可以通过断言 on 来修复它Class

Throwable throwable =  assertThrows(Throwable.class, () -> {
    LibraryUserDetailsService.getUserByEmail("mokal006@gmail.com");
});
assertEquals(UserNotFoundException.class, throwable.getClass());

或使用此处的解决方案JUnit 5: How to assert an exception is throwed?

[编辑]

正如johanneslink在评论中指出的那样,user.orElseThrow将永远不会被执行。userDao.findByEmailAddress(...)将抛出UserNotFoundException,因为没有catch块异常将传播回调用者,因此BadRequestException不会被抛出并且测试用例将始终通过。


推荐阅读