JUnit 5 遇上 AssertJ

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(86)   2024-04-23 16:20:41

JUnit 5 对断言库进行了大量改进,这主要归功于 Java 8 和 Lambda 表达式的支持,以及新断言的出现,例如 assertAllassertTimeoutassertThrows。虽然我真的很喜欢 JUnit 5,但我相信 AssertJ 仍然是生产级单元测试的必备工具,我会继续使用它。

但我认为在单个单元测试中存在混合 JUnit 5 和 AssertJ 的潜在场景:其中之一是将 JUnit assertAll 与 AssertJ assertThat 混合。

JUnit 5 – assertAll

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 将被跳过。

AssertJ——软断言

注意:我在这篇文章中写了更多关于 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 assertAll 与 AssertJ assertThat 混合使用

将 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

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...