适用于 Idea 的面向现代 TDD 的 Java 8 JUnit 测试模板(使用 Mockito 和 AssertJ)

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(581)   2024-01-29 07:14:57

使用类似 BDD 的语法、Java 8 和 Mockito-AssertJ duo 调整 Idea 的 JUnit 测试类模板。

本文涵盖的主题可能看起来微不足道。但是,根据我的培训师 经验,我知道(不幸的是)这不是一种常见的做法。因此,我决定写这篇简短的博文来宣传他们,以备日后参考。

我最喜欢的 Java(和 Groovy)测试框架是 Spock。然而,它的模拟不适合某些目的,我仍然在各个地方使用 Mockito。此外,我仍然在 JUnit/Mockito/AssertJ 变体中为已经在该堆栈中拥有测试套件并希望在不改变已知技术的情况下提高技能的团队进行大量的测试培训 .因此,作为插曲,这篇关于以纯 Java 风格进行测试的博客文章提出了如何在假设您已经在使用 Mockito 和 AssertJ 的情况下调整您的 JUnit 测试框架(在其他情况下您应该尝试一下)。

这篇博文由树部分组成。首先,我提出了一种 BDD 风格的基于部分的测试结构,以使您的测试更加一致和更具可读性。接下来,我将解释如何使用 AssertJ 和 Mockito 简化 Java 8 的构造。最后但同样重要的是,我将展示如何在 IntelliJ IDEA 中将其配置为默认的 JUnit 测试(类)模板(这并不像它应该)。

第 1 部分 BDD 样式部分

编写良好的单元测试应该满足几个要求(但这是另一篇文章的主题)。一种有用的做法是明确划分为 3 个代码块,并明确定义职责。您可以在我之前的博文中阅读有关该主题的更多信息。

作为重复,只是以简短形式呈现的核心规则:

  • given – 一个被测试初始化的对象 + 存根/模拟创建、存根和注入
  • when – 在给定测试中测试的操作
  • then – 收到结果断言 + 模拟验证(如果需要)
@Test
public void shouldXXX() {
  //given
  ...
  //when
  ...
  //then
  ...
}

这种分离有助于保持测试简短,并只专注于一个测试职责(最终它只是一个单元测试)。

在 Spock 中,这些部分是强制性的 (*)——没有它们,测试甚至无法编译。在 JUnit 中只有注释。但是,将它们放在适当的位置会鼓励人们使用它们,而不是在里面放一大块乱七八糟的东西(对测试区域的新手特别有用)。

顺便说一句,上面提到的 given-when-then 约定基于(是一个子集)一个更广泛的行为驱动开发概念。您可能会在名为 arrange-act-assert 的 3 个代码块上遇到类似的划分,这通常是等价的。

第 2 部分。用于 AssertJ 和 Mockito 的 Java 8

Java 8 的特性之一是能够将默认方法放入接口中。这可用于简化调用静态方法,这在 AssertJ 和 Mockito 等测试框架中很普遍。这个想法很简单。愿意使用给定框架的测试类可以实现一个专用接口,以在 IDE 中的代码完成时将这些方法“视为”自己的方法(而不是来自外部类的静态方法,这些方法需要在之前给出类名或静态导入) .在幕后,这些默认方法只是将执行委托给静态方法。您可以在我的另一篇博文 中更多参考相关信息。

AssertJ 原生支持从 3.0.0 版本开始的那些构造。 Mockito 1.10 和 2.x 与 Java 6 兼容,因此需要使用第 3 方项目——mockito-java8(应该集成到 Mockito 3 中——一旦可用)。

为了从 Idea 中更简单的方法完成中获益,实现两个接口就足够了:

import info.solidsoft.mockito.java8.api.WithBDDMockito;
import org.assertj.core.api.WithAssertions;

class SampleTest implements WithAssertions, WithBDDMockito {

}

第 3 部分。Idea 中的默认模板

我是无处不在的自动化的忠实拥护者。在您的测试类中自动放置 given-when-then 部分和额外的接口不是很好吗?让我们从生活中消除那些无聊的事情。

测试方法

更改 JUnit 测试方法很容易。一种可能的方法是“CTRL-SHIFT-A -> 文件模板 -> 代码”并将 JUnit4 Test Method 修改为:

@org.junit.Test
public void should${NAME}() {
  //given
  ${BODY}
  //when
  //then
}

要在现有测试类中添加新测试,只需按 ALT-INSERT 并选择(或键入)JUnit4 Test Method

测试类

对于整个测试班,情况有点复杂。 Idea 提供了一种编辑现有模板的方法,但是,仅当使用生产类中的 CTRL-SHIFT-T 生成测试时才使用它。对于应该首先创建测试的 TDD,这不是很方便。如果在测试上下文中的包视图中按下 ALT-INSERT,那么在“Java 类”旁边显示一个新位置“New JUnit test class”会很好。不幸的是,为此需要编写一个新插件(Spock 的示例实现)。作为一种解决方法,我们可以定义一个常规文件模板(作为限制)可以在任何地方访问(例如,甚至在资源目录中)。

执行“CTRL-SHIFT-A -> 文件模板 -> 文件”,按 INSERT,将模板命名为“JUnit with AssertJ and Mockito Test”,将扩展名设置为“java”并粘贴以下模板:

package ${PACKAGE_NAME};

import info.solidsoft.mockito.java8.api.WithBDDMockito;
import org.assertj.core.api.WithAssertions;

#parse("File Header.java") 
public class ${NAME} implements WithAssertions, WithBDDMockito {

}

展柜

我们已经准备好了。让我们看看它在实践中的样子(点击放大动画)。

概括

我希望我说服您调整您的测试模板以提高测试的可读性并确保每次测试多次击键。如果是这样,请立即花 4 分钟在您的 Idea 中进行配置。根据编写的大量测试,它可能会比您预期的更早开始获得回报 :)。

顺便说一句,10 月初,我将在克拉科夫的 JDD 上做一个关于 Mockito 2 新功能的演示

自我推销。你想快速有效地提高你和你的团队的测试技能和 Spock/JUnit/Mockito/AssertJ 的知识吗?我进行了浓缩(单元)测试培训,您可能会发现它很有用。

标签2: Java教程
地址:https://www.cundage.com/article/jcg-modern-tdd-oriented-java-8-junit-test-template-idea-mockito-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 提...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...