JUnit assertThrows中的Executable会发生什么?

时间:2019-09-01 11:48:37

标签: java junit5 functional-interface

我了解Junit5 Assertions.assertThrows接受一个可执行类型对象。因此,对于一个简单的示例,其中构造函数可能不会将空字符串作为名称参数:

public Company(String aName, Calendar aFoundingDate)
{
    if (aName == null || aName.length() == 0 || aName.length() > 50) {
        throw new IllegalArgumentException("Invalid name");
    }
    this.name = aName;
    foundingDate = aFoundingDate;
}

我可以这样编写测试:

// Company constructor test
@Test
void testCompanyConstructor() {
    // Given
    String emptyName = "aabbe";
    Calendar validFoundingDate = Calendar.getInstance();
    validFoundingDate.set(2000, 1, 1);

    // Then
    assertThrows(IllegalArgumentException.class, () -> new Company(emptyName, validFoundingDate));
}

我想知道的是,可执行文件(即Lambda表达式)如何处理? JUnit是否在Lambda表达式上调用execute(),这样做时,将创建具有空名称的匿名公司Object,并且例外是

附录: 这些版本等效:

// Company constructor test
@Test
void testCompanyConstructor() {
    // Given
    String emptyName = "";
    Calendar validFoundingDate = Calendar.getInstance();
    validFoundingDate.set(2000, 1, 1);

    // Then
    Executable executable = new Executable() {
        public void execute() {
            new Company(emptyName, validFoundingDate);
        }
    };
    assertThrows(IllegalArgumentException.class, executable);
    assertThrows(IllegalArgumentException.class, () -> new Company(emptyName, validFoundingDate));
}

2 个答案:

答案 0 :(得分:2)

是的,这正是发生的情况。 JUnit在一个内部运行Executable try { ... } catch (Throwable t) {...}块。如果捕获的异常是指定的类型,则一切正常。如果不是,那么它将引发AssertionError。

答案 1 :(得分:2)

在检查import package的代码时,我们可以很深地发现assertThrows中放置了这样的代码:

AssertThrows::assertThrows

因此,它基本上会调用try { executable.execute(); } catch (Throwable actualException) if (expectedType.isInstance(actualException)) { return (T) actualException; } else { BlacklistedExceptions.rethrowIfBlacklisted(actualException); String message = buildPrefix(nullSafeGet(messageOrSupplier)) + format(expectedType, actualException.getClass(), "Unexpected exception type thrown"); throw new AssertionFailedError(message, actualException); } } 并捕获可能引发的Executable并返回它。如果未引发任何异常或异常的类型与预期的不同,则断言将失败。