1. 概述
在编写单元测试时,我们有时会对输出进行多条断言。一旦第一条断言失败,测试就会停止,这意味着我们无法得知后续断言的结果,这可能会增加调试时间。
为了解决这个问题,我们可以将多个断言组合成一个操作。
在这个简短的教程中,我们将学习如何使用JUnit5引入的assertAll()
方法,并了解它与使用多个独立断言有何不同。
2. 模型
我们将使用一个User
类来举例说明:
public class User {
String username;
String email;
boolean activated;
//constructors
//getters and setters
}
3. 使用多个断言
让我们从所有断言都会失败的例子开始:
User user = new User("baeldung", "[email protected]", false);
assertEquals("admin", user.getUsername(), "Username should be admin");
assertEquals("[email protected]", user.getEmail(), "Email should be [email protected]");
assertTrue(user.getActivated(), "User should be activated");
运行测试后,只会显示第一条断言的失败:
org.opentest4j.AssertionFailedError: Username should be admin ==>
Expected :admin
Actual :baeldung
假设我们修复了失败的代码或测试并重新运行,那么会得到第二个失败,依此类推。在这种情况下,将这些断言组合成单个通过/失败情况会更好。
4. 使用assertAll()
方法
我们可以使用JUnit5的assertAll()
方法来分组断言。
4.1. assertAll()
的理解
assertAll()
断言函数接受一个包含多个Executable
对象的集合:
assertAll(
"Grouped Assertions of User",
() -> assertEquals("baeldung", user.getUsername(), "Username should be baeldung"),
// more assertions
...
);
因此,我们可以使用lambda表达式提供每个断言。lambda将在assertAll()
提供的分组内执行断言。
在这里,在assertAll()
的第一个参数中,我们也提供了描述,以解释整个组的意义。
4.2. 使用assertAll()
分组断言
让我们看看完整的例子:
User user = new User("baeldung", "[email protected]", false);
assertAll(
"Grouped Assertions of User",
() -> assertEquals("admin", user.getUsername(), "Username should be admin"),
() -> assertEquals("[email protected]", user.getEmail(), "Email should be [email protected]"),
() -> assertTrue(user.getActivated(), "User should be activated")
);
现在,我们来看看当运行测试时会发生什么:
org.opentest4j.MultipleFailuresError: Grouped Assertions of User (3 failures)
org.opentest4j.AssertionFailedError: Username should be admin ==> expected: <admin> but was: <baeldung>
org.opentest4j.AssertionFailedError: Email should be [email protected] ==> expected: <[email protected]> but was: <[email protected]>
org.opentest4j.AssertionFailedError: User should be activated ==> expected: <true> but was: <false>
与使用多个独立断言的情况相反,这次所有断言都被执行,并且它们的失败信息都包含在MultipleFailuresError
消息中。
需要注意的是,assertAll()
仅处理AssertionError
。如果任何断言以异常结束,而不是通常的AssertionError
,则立即停止执行,并将错误输出与异常相关,而不是MultipleFailuresError
。
5. 总结
在这篇文章中,我们学会了在JUnit5中使用assertAll()
,并了解了它与使用多个单独断言的区别。
如往常一样,本教程的完整代码可以在GitHub上找到:GitHub链接。