简体   繁体   English

JUnit assertThrows中的Executable会发生什么?

[英]What happens with the Executable in a JUnit assertThrows?

I understand that Junit5 Assertions.assertThrows accepts an Executable type object. 我了解Junit5 Assertions.assertThrows接受一个可执行类型对象。 So for a simple example where a Constructor may not take an empty string as a name parameter: 因此,对于一个简单的示例,在该示例中,构造函数不能将空字符串用作名称参数:

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;
}

I can write a test like this: 我可以编写这样的测试:

// 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));
}

What I wonder is, what happens to the executable, ie the Lambda Expression? 我想知道的是,可执行文件(即Lambda表达式)如何处理? Does JUnit call execute() on the Lambda expression and in doing so, the anonymous company Object with the empty name is created and the exception is JUnit是否在Lambda表达式上调用execute(),这样做时,将创建具有空名称的匿名公司Object,并且例外是

Appendix: These versions are equivalent: 附录:这些版本等效:

// 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));
}

Yes that's precisely what happens. 是的,这正是发生的情况。 JUnit runs the Executable inside a try { ... } catch (Throwable t) {...} block. JUnit在try { ... } catch (Throwable t) {...}块中运行Executable。 If the exception caught is of the specified type, then all is good. 如果捕获的异常是指定的类型,则一切正常。 If not then it throws an AssertionError. 如果不是,则抛出AssertionError。

When inspecting the code of assertThrows we can see that deeply there is such code placed in AssertThrows::assertThrows : 在检查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);
    }
}

so it basically invokes Executable and catches Throwable that might be thrown and returns it. 因此它基本上会调用Executable并捕获可能抛出的Throwable并返回它。 If no exception was thrown or the type of exception is different than expected - the assertion fails. 如果未引发任何异常或异常的类型与预期的不同,则断言失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM