目录

一、JUnit5 的变化

1.介绍

2.使用

二、JUnit5常用注解

1.JUnit5的注解与JUnit4的注解有所变化

2.@DisplayName

3.@BeforeEach、@AfterEach、@BeforeAll、@AfterAll

4.@Disabled

5.@Timeout

6.@SpringBootTest

7.@RepeatedTest

三、断言

1.简介

2.简单断言

3.数组断言

4.组合断言

5.异常断言

6.超时断言

7.快速失败

四、前置条件(assumptions)

五、嵌套测试

六、参数化测试

七、迁移指南


一、JUnit5 的变化

1.介绍

Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库

作为最新版本的JUnit框架,JUnit5与之前版本的Junit框架有很大的不同。由三个不同子项目的几个不同模块组成。

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

JUnit Platform: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。

JUnit Jupiter: JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行。

JUnit Vintage: 由于JUint已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。

注意:

SpringBoot 2.4 以上版本移除了默认对 Vintage 的依赖。如果需要兼容junit4需要自行引入(不能使用junit4的功能 @Test)

JUnit 5’s Vintage Engine Removed from spring-boot-starter-test,如果需要继续兼容junit4需要自行引入vintage

<dependency><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.hamcrest</groupId><artifactId>hamcrest-core</artifactId></exclusion></exclusions>
</dependency>

2.使用

(1)引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

(2)使用

Junit类具有Spring的功能,@Autowired、比如 @Transactional 标注测试方法,测试完成后自动回滚

@SpringBootTest
class Boot05WebAdminApplicationTests {@Test // @Test标注(注意需要使用junit5版本的注解)void contextLoads() {}
}

二、JUnit5常用注解

1.JUnit5的注解与JUnit4的注解有所变化

JUnit 5 User Guide

* @Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试

* @ParameterizedTest :表示方法是参数化测试,下方会有详细介绍

* @RepeatedTest :表示方法可重复执行,下方会有详细介绍

* @DisplayName :为测试类或者测试方法设置展示名称

* @BeforeEach :表示在每个单元测试之前执行

* @AfterEach :表示在每个单元测试之后执行

* @BeforeAll :表示在所有单元测试之前执行

* @AfterAll :表示在所有单元测试之后执行

* @Tag :表示单元测试类别,类似于JUnit4中的@Categories

* @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore

* @Timeout :表示测试方法运行如果超过了指定时间将会返回错误

* @ExtendWith :为测试类或测试方法提供扩展类引用

2.@DisplayName

@DisplayName("junit5功能测试类")
public class Junit5Test {@DisplayName("测试displayname注解")@Testvoid testDisplayName() {System.out.println(1);}
}

3.@BeforeEach、@AfterEach、@BeforeAll、@AfterAll

@BeforeEach
void testBeforeEach() {System.out.println("测试就要开始了...");
}@AfterEach
void testAfterEach() {System.out.println("测试结束了...");
}@BeforeAll // 必须静态方法
static void testBeforeAll() {System.out.println("所有测试就要开始了...");
}@AfterAll // 必须静态方法
static void testAfterAll() {System.out.println("所有测试已经结束了...");
}

4.@Disabled

执行测试类会执行所有测试方法,但是标注@Disabled的测试方法不会执行。

@Disabled
@DisplayName("测试方法2")
@Test
void test2() {System.out.println(2);
}

5.@Timeout

/**
* 规定方法超时时间。超出时间测试出异常
*
* @throws InterruptedException
*/
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS)
@Test
void testTimeout() throws InterruptedException {Thread.sleep(600);
}

6.@SpringBootTest

注释在类上,可以使用springboot的容器等功能。

7.@RepeatedTest

@RepeatedTest(5)
@Test
void test3() {System.out.println(5);
}

三、断言

1.简介

断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法。JUnit 5 内置的断言可以分成如下几个类别:

检查业务逻辑返回的数据是否合理。

所有的测试运行结束以后,会有一个详细的测试报告。

2.简单断言

用来对单个值进行简单的验证。如:

方法

说明

assertEquals

判断两个对象或两个原始类型是否相等

assertNotEquals

判断两个对象或两个原始类型是否不相等

assertSame

判断两个对象引用是否指向同一个对象

assertNotSame

判断两个对象引用是否指向不同的对象

assertTrue

判断给定的布尔值是否为 true

assertFalse

判断给定的布尔值是否为 false

assertNull

判断给定的对象引用是否为 null

assertNotNull

判断给定的对象引用是否不为 null

/**
* 断言:前面断言失败,后面的代码都不会执行
*/
@DisplayName("测试简单断言")
@Test
void testSimpleAssertions() {int cal = cal(3, 2);//相等assertEquals(6, cal, "业务逻辑计算失败");Object obj1 = new Object();Object obj2 = new Object();assertSame(obj1, obj2, "两个对象不一样");
}int cal(int i, int j) {return i + j;
}// 运行结果
org.opentest4j.AssertionFailedError: 业务逻辑计算失败 ==>
Expected :6
Actual   :5
<Click to see difference>at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:150)at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:542)……

3.数组断言

通过 assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等

@Test
@DisplayName("array assertion")
void array() {assertArrayEquals(new int[]{1, 2}, new int[]{1, 2}, "数组内容不相等");
}

4.组合断言

assertAll 方法接受多个 org.junit.jupiter.api.Executable 函数式接口的实例作为要验证的断言,可以通过 lambda 表达式很容易的提供这些断言

@Test
@DisplayName("组合断言")
void all() {/*** 所有断言全部需要成功*/assertAll("test",() -> assertTrue(true && true, "结果不为true"),() -> assertEquals(1, 2, "结果不是1"));System.out.println("=====");
}

5.异常断言

在JUnit4时期,想要测试方法的异常情况时,需要用@Rule注解的ExpectedException变量还是比较麻烦的。而JUnit5提供了一种新的断言方式Assertions.assertThrows() ,配合函数式编程就可以进行使用。

@DisplayName("异常断言")
@Test
void testException() {//断定业务逻辑一定出现异常assertThrows(ArithmeticException.class, () -> {int i = 10 / 2;}, "业务逻辑居然正常运行?");
}

6.超时断言

Junit5还提供了Assertions.assertTimeout() 为测试方法设置了超时时间

@Test
@DisplayName("超时测试")
public void timeoutTest() {//如果测试方法时间超过1s将会异常Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(500));
}

7.快速失败

通过 fail 方法直接使得测试失败

@DisplayName("快速失败")
@Test
void testFail(){//xxxxxif(2 == 2){fail("测试失败");}
}

四、前置条件(assumptions)

JUnit 5 中的前置条件(assumptions【假设】)类似于断言,不同之处在于不满足的断言会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行终止。前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要。

assumeTrue 和 assumFalse 确保给定的条件为 true 或 false,不满足条件会使得测试执行终止。assumingThat 的参数是表示条件的布尔值和对应的 Executable 接口的实现对象。只有条件满足时,Executable 对象才会被执行;当条件不满足时,测试执行并不会终止。

/**
* 测试前置条件
*/
@DisplayName("测试前置条件")
@Test
void testassumptions(){Assumptions.assumeTrue(false,"结果不是true");System.out.println("111111");
}
@DisplayName("前置条件")
public class AssumptionsTest {private final String environment = "DEV";@Test@DisplayName("simple")public void simpleAssume() {assumeTrue(Objects.equals(this.environment, "DEV"));assumeFalse(() -> Objects.equals(this.environment, "PROD"));}@Test@DisplayName("assume then do")public void assumeThenDo() {assumingThat(Objects.equals(this.environment, "DEV"),() -> System.out.println("In DEV"));}
}

五、嵌套测试

JUnit 5 可以通过 Java 中的内部类和@Nested 注解实现嵌套测试,从而可以更好的把相关的测试方法组织在一起。在内部类中可以使用@BeforeEach 和@AfterEach 注解,而且嵌套的层次没有限制。

@DisplayName("A stack")
class TestingAStackDemo {Stack<Object> stack;@Test@DisplayName("is instantiated with new Stack()")void isInstantiatedWithNew() {new Stack<>();//嵌套测试情况下,外层的Test不能驱动内层的Before(After)Each/All之类的方法提前/之后运行assertNull(stack);}@Nested // 代表是嵌套测试@DisplayName("when new")class WhenNew {@BeforeEach // 所有测试之前执行,嵌套类中不会在外面执行void createNewStack() {stack = new Stack<>();}@Test@DisplayName("is empty")void isEmpty() {assertTrue(stack.isEmpty());}@Test@DisplayName("throws EmptyStackException when popped")void throwsExceptionWhenPopped() {assertThrows(EmptyStackException.class, stack::pop);}@Test@DisplayName("throws EmptyStackException when peeked")void throwsExceptionWhenPeeked() {assertThrows(EmptyStackException.class, stack::peek);}@Nested@DisplayName("after pushing an element")class AfterPushing {String anElement = "an element";@BeforeEachvoid pushAnElement() {stack.push(anElement);}/*** 内层的Test可以驱动外层的Before(After)Each/All之类的方法提前/之后运行*/@Test@DisplayName("it is no longer empty")void isNotEmpty() {assertFalse(stack.isEmpty());}@Test@DisplayName("returns the element when popped and is empty")void returnElementWhenPopped() {assertEquals(anElement, stack.pop());assertTrue(stack.isEmpty());}@Test@DisplayName("returns the element when peeked but remains not empty")void returnElementWhenPeeked() {assertEquals(anElement, stack.peek());assertFalse(stack.isEmpty());}}}
}

六、参数化测试

参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利。

利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。

@ValueSource: 为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型

@NullSource: 表示为参数化测试提供一个null的入参

@EnumSource: 表示为参数化测试提供一个枚举入参

@CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参

@MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)

当然如果参数化测试仅仅只能做到指定普通的入参还达不到让我觉得惊艳的地步。让我真正感到他的强大之处的地方在于他可以支持外部的各类入参。如:CSV,YML,JSON 文件甚至方法的返回值也可以作为入参。只需要去实现ArgumentsProvider接口,任何外部文件都可以作为它的入参。

@ParameterizedTest
@DisplayName("参数化测试")
@ValueSource(ints = {1,2,3,4,5})
void testParameterized(int i){System.out.println(i);
}@ParameterizedTest
@DisplayName("参数化测试")
@MethodSource("stringProvider")
void testParameterized2(String i){System.out.println(i);
}static Stream<String> stringProvider() {return Stream.of("apple", "banana","atguigu");
}

七、迁移指南

在进行迁移的时候需要注意如下的变化:

* 注解在 org.junit.jupiter.api 包中,断言在 org.junit.jupiter.api.Assertions 类中,前置条件在 org.junit.jupiter.api.Assumptions 类中。

* 把@Before 和@After 替换成@BeforeEach 和@AfterEach。

* 把@BeforeClass 和@AfterClass 替换成@BeforeAll 和@AfterAll。

* 把@Ignore 替换成@Disabled。

* 把@Category 替换成@Tag。

* 把@RunWith、@Rule 和@ClassRule 替换成@ExtendWith。

springboot2使用JUnit5单元测试使用大全相关推荐

  1. java每日Demo之junit5单元测试

    提示:内容纯属实战运用,不玩虚的.看明白就可以用在工作中,现学现用. 文章目录 前言 一.为什么要使用mock(Mockito)? 验证和断言 给Mock对象打桩 @Mock注解 @BeforeEac ...

  2. W2-2:在Maven项目中进行Junit5单元测试

    系列文章目录 W2-1:Maven引入外部依赖--以GSON的使用为例 W2-2:在Maven项目中进行Junit5单元测试 - 环境:IntelliJ IDEA Community Edition ...

  3. JUnit5单元测试框架的使用教程与简单实例

    1.JUnit5的使用教程 1.1 简介 JUnit是一个Java语言的单元测试框架.它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最 ...

  4. Junit5单元测试的常用注解

    JUnit5的注解与JUnit4的注解有所变化 https://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations ...

  5. Spring Boot 集成 JUnit5,更优雅单元测试!

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:https://mp.weixin.qq.com/s/2Kdu-nYLF55Ui9A1-ybgFw 为什么使用JUnit5 J ...

  6. 单元测试框架怎么搭?快来看看新版Junit5的这些神奇之处吧!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 为什么使用JUnit5 JUnit4被广泛使用,但是许多场 ...

  7. java中的jar包以及单元测试

    1. jar包 jar包是什么? jar包:是java中的特殊的一种压缩格式的包 jar包中压缩的是class文件,把jar包提供给需要的项目使用 导出jar包的步骤: 右键单击要导出的jar包的项目 ...

  8. SpringBoot对单元测试支持、常用单元测试功能使用实例

    SpringBoot 单元测试 Spring Boot 提供了许多注解和工具帮助开发人员测试应用,在其官方文档中也用了大量篇幅介绍单元测试的使用.在谷歌每周的 TGIF (ThanksGod, it' ...

  9. 经典再现,看到就是赚到。尚硅谷雷神 - SpringBoot 2.x 学习笔记 -高级与场景整合篇

    SpringBoot 2.x 场景整合 在上一篇核心功能篇里,我们已了解SpringBoot的配置文件.web开发.数据访问.JUnit5单元测试.生产指标监控.SpringBoot启动流程等.然而S ...

最新文章

  1. C#仿QQ皮肤系列之-引言
  2. Amazon S3数据一致性模型
  3. 今天我才明白了泛型,泛型类 泛型方法
  4. Sklearn专题实战——数据处理+模型构建+网格搜索+保存(提取)模型
  5. 数据分析数据挖掘(三)
  6. mac下chrome浏览器设置ajax跨域调试
  7. Angularjs中$http以post请求通过消息体传递参数
  8. PoEdu - C++阶段班【Po学校】- 第1课
  9. Python 打包的EXE文件反编译1|EXE文件反编译为pyc文件
  10. 用正则表达式验证邮箱和手机号
  11. 这 9 个 Java 开源项目 yyds
  12. 三菱plc控制步进电机实例_「PLC案例」三菱FX3U与威纶通HMI的步进定位控制,附程序图~...
  13. JDBC,你真的知道怎么用吗?
  14. 前端国密加解密使用方法SM2、SM3、SM4
  15. 服务器虚拟机光驱,vSphere client中的光驱配置方式
  16. heartbeat: ha.cf配置文件中文详解
  17. Kitty用HTML和css咋做,使用 CSS3 绘制 Hello Kitty
  18. shell 语句出错自动退出
  19. Python replace()方法
  20. PHP计算两个日期相差的天数方法详解

热门文章

  1. JUC系列(五)| Synchonized关键字进一步理解
  2. python做Linux进程运行,Python实现在Linux系统下更改当前进程运行用户
  3. async function_Electron IPC 通信如何使用 async/await 调用?
  4. 怎么通过name配置button_利器 | AppCrawler 自动遍历测试实践(二):定制化配置
  5. USB转串口TTL板RX电平异常导致无法收到数据
  6. centos找不到chattr命令_一个骚命令防止你的文件被误删除!
  7. kylin安装mysql_源码安装mysql
  8. gitlab 更新文件_GitLab任意文件读取漏洞公告
  9. html语言 section type,HTML5中div、article、section的区别及使用介绍
  10. cc2530期末试卷_无线传感网期末考试 zigbee期末考试试题