JUnit 5 对断言库进行了大量改进,这主要归功于 Java 8 和 Lambda 表达式的支持,以及新断言的出现,例如 assertAll
、assertTimeout
或 assertThrows
。虽然我真的很喜欢 JUnit 5,但我相信 AssertJ 仍然是生产级单元测试的必备工具,我会继续使用它。
但我认为在单个单元测试中存在混合 JUnit 5 和 AssertJ 的潜在场景:其中之一是将 JUnit assertAll
与 AssertJ assertThat
混合。
Assertions.assertAll
断言所有提供的可执行文件都不会抛出异常:
List<String> owners = Arrays.asList("Betty Davis", "Eduardo Rodriquez"); // assert assertAll( () -> assertTrue(owners.contains("Betty Doe"), "Contains Betty Doe"), () -> assertTrue(owners.contains("John Doe"), "Contains John Doe"), () -> assertTrue(owners.contains("Eduardo Rodriquez"), "Eduardo Rodriquez") );
上面会报2个错误:
org.opentest4j.MultipleFailuresError: Multiple Failures (2 failures) Contains Betty Doe ==> expected: <true> but was: <false> Contains John Doe ==> expected: <true> but was: <false>
assertAll
执行所有传递的可执行文件并确保所有传递(不抛出异常)。换句话说,assertAll
允许分组断言。
此外,assertAll
可用于创建依赖断言:
List<String> owners = Arrays.asList("Betty Davis", "Eduardo Rodriquez"); // assert assertAll( () -> { assertTrue(owners.contains("Betty Doe"), "Contains Betty Doe"); assertAll( () -> assertNotNull(owners), () -> assertTrue(owners.size() > 1) ); } );
在上面的示例中,当第一个 assertTrue
失败时,后续的 assertAll
将被跳过。
注意:我在这篇文章中写了更多关于 SoftAssertions 的文章:AssertJ soft assertions – Do we need them?
AssertJ
提供的 SoftAssertions
基本上与 JUnit 5 assertAll
的功能相同,只是不支持依赖断言。
List<String> owners = Arrays.asList("Betty Davis", "Eduardo Rodriquez"); assertSoftly( softAssertions -> { softAssertions.assertThat(owners).contains("Betty Doe"); softAssertions.assertThat(owners).contains("John Doe"); softAssertions.assertThat(owners).contains("Eduardo Rodriquez"); } );
报告的错误:
1) Expecting: <["Betty Davis", "Eduardo Rodriquez"]> to contain: <["Betty Doe"]> but could not find: <["Betty Doe"]> at AssertJAssertionsTest.lambda$assertsSoftly$0(AssertJAssertionsTest.java:26) 2) Expecting: <["Betty Davis", "Eduardo Rodriquez"]> to contain: <["John Doe"]> but could not find: <["John Doe"]>
将 JUnit 5 assertAll
与 AssertJ assertThat
断言混合使用似乎是一个不错的选择:
// arrange String givenName = "Jean"; String expectedCity = "Monona"; String expectedAddress = "105 N. Lake St."; // act Optional<Owner> result = testObj.findByName(givenName); // assert assertThat(result).isPresent(); assertAll( () -> assertThat(result.get().getFirstName()).isEqualTo(givenName), () -> assertThat(result.get().getCity()).isEqualTo(expectedCity), () -> assertThat(result.get().getAddress()).isEqualTo(expectedAddress) );
另一方面,assertAll
可以用作 assertThat
的参数:
// arrange String givenName = "Jean"; String expectedCity = "Monona"; String expectedAddress = "105 N. Lake St."; // act Optional<Owner> result = testObj.findByName(givenName); // assert assertThat(result).hasValueSatisfying(owner -> assertAll( () -> assertThat(owner.getFirstName()).isEqualTo(givenName), () -> assertThat(owner.getCity()).isEqualTo(expectedCity), () -> assertThat(owner.getAddress()).isEqualTo(expectedAddress) ));
尽管 JUnit 5 是一个很棒的框架并且它提供了很多断言,但我相信无论如何都需要像 AssertJ 这样的第 3 方断言库来为断言增添趣味。我已经使用 AssertJ 好几年了,我认为我不会放弃它。但我确实在我的测试中看到了新 JUnit 5 assertAll
的空间。特别是在集成测试中。
这篇博文中的所有示例(以及更多)都可以在这个 GitHub 存储库中找到:https://github.com/kolorobot/junit5-samples*
* 非常感谢 Maciej Koziara 为这个存储库做出了贡献。
标签2: Java教程地址:https://www.cundage.com/article/jcg-junit-5-meets-assertj.html