我了解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));
}

最佳答案

检查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并捕获可能抛出的Throwable并返回它。如果未引发任何异常或异常的类型与预期的不同,则断言失败。

10-04 20:30