SpringBoot基础(五):集成JUnit5

SpringBoot基础系列文章

SpringBoot基础(一):快速入门

SpringBoot基础(二):配置文件详解

SpringBoot基础(三):Logback日志

SpringBoot基础(四):bean的多种加载方式

SpringBoot基础(五):集成JUnit5


目录

  • 一、JUnit5介绍
    • 1、JUnit5组成结构
    • 2、什么是单元测试
  • 二、SpringBoot整合JUnit5
    • 1、快速入门
    • 2、测试类和测试方法不需要声明为public
    • 3、@SpringBootTest工作原理
    • 4、生成单元测试类
  • 三、常用注解
    • 1、@BeforeAll
    • 2、@AfterAll
    • 3、@BeforeEach
    • 4、@AfterEach
    • 5、@DisplayName
    • 6、@Disabled
    • 7、@RepeatedTest
  • 四、常用断言
    • 1、assertEquals(expected, actual)
    • 2、assertNotEquals(expected, actual)
    • 3、assertTrue(condition)
    • 4、assertFalse(condition)
    • 5、assertNull(actual)
    • 6、assertNotNull(actual)
    • 7、assertArrayEquals(expected, actual)
    • 8、assertSame(expected, actual)
    • 9、assertNotSame(expected, actual)
    • 10、fail(message)
    • 11、带有消息参数的断言
  • 五、@MockBean注入
    • 1、@MockBean的主要作用
    • 2、@MockBean的典型用法(模拟数据层)

一、JUnit5介绍

  JUnit5是一个功能强大的单元测试框架,是JUnit系列的最新版本,它引入了多个改进和新特性,旨在为Java应用程序提供灵活且模块化的测试支持。

1、JUnit5组成结构

  • JUnit Platform:这个模块提供了测试的启动API和运行环境,是整个JUnit5框架的核心。它支持在不同的环境中运行测试,如命令行、IDE或构建工具(例如Maven、Gradle)
  • JUnit Jupiter:这个模块包含了JUnit5的新测试编写和扩展模型,提供了全新的注解、测试方法和扩展机制
  • JUnit Vintage:为了支持旧版本的JUnit测试(JUnit3和JUnit4),JUnit5提供了Vintage模块。这个模块允许开发者继续运行以前版本的测试,同时过渡到JUnit5

2、什么是单元测试

  • 单元测试是指对软件中的最小可测试单元进行检查和验证的过程叫单元测试
  • SpringBoot中,最小可测试单元就是指方法

二、SpringBoot整合JUnit5

1、快速入门

  • SpringBoot版本从2.2以后,默认支持JUnit5
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
  • 测试类应放在src/test/java目录下

在这里插入图片描述

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class MySpringBootApplicationTests {@Testvoid contextLoads() {// 测试 Spring 应用上下文是否成功加载}
}

2、测试类和测试方法不需要声明为public

  • JUnit4中,测试类和测试方法必须是public的,因为JUnit4通过反射机制要求访问公共方法
  • JUnit5则没有这种要求,测试类和方法的可见性设为包级(默认)足够 JUnit 5 框架执行测试
    • 因为 JUnit 5 本质上是在测试框架内部执行这些测试
    • 包级别的可见性允许同一包内的类访问测试类,而不需要将其暴露为 public

3、@SpringBootTest工作原理

  它会启动整个Spring容器,加载应用程序的所有Bean,并创建一个完整的应用上下文。这是集成测试,因为它模拟了应用程序的真实运行环境。

查找主配置类的两种方式:

  包扫描:默认情况下,@SpringBootTest 会从测试类所在的包开始,向上查找同一包或父包中带有 @SpringBootApplication@SpringBootConfiguration注解的类,作为应用的配置类

在这里插入图片描述

  显式指定:如果 @SpringBootTest 无法自动找到 @SpringBootApplication 注解的配置类,或者你希望手动指定配置类,你可以在@SpringBootTest 注解中使用classes属性显式指定应用的配置类

在这里插入图片描述

4、生成单元测试类

  • 在需要生成单元测试的类中按Alt +Ins,选择test(测试)

在这里插入图片描述

  • 选择测试方法

在这里插入图片描述

  • 生成的测试类放入与本类相同的包结构

在这里插入图片描述

三、常用注解

1、@BeforeAll

  • 用于在所有测试方法之前执行的静态初始化代码
  • 通常用于在执行所有测试之前进行一次性设置,例如建立数据库连接、初始化共享资源等
  • 被注解的方法必须是static
@BeforeAll
static void setup() {System.out.println("Running setup before all tests...");
}

2、@AfterAll

  • 用于在所有测试方法执行完成后运行的静态清理代码
  • 通常用于释放资源、关闭连接等操作
  • 被注解的方法必须是static
@AfterAll
static void tearDown() {System.out.println("Running teardown after all tests...");
}

3、@BeforeEach

  • 用于在每个测试方法之前执行的初始化代码
  • 常用于在每个测试方法执行之前准备一些通用的数据或环境
@BeforeEach
void init() {System.out.println("Running setup before each test...");
}

4、@AfterEach

  • 用于在每个测试方法之后执行的清理代码
  • 常用于在每个测试方法之后恢复原状或清理一些资源
@AfterEach
void cleanup() {System.out.println("Running cleanup after each test...");
}

5、@DisplayName

  • 用于为测试类或测试方法提供一个更具可读性或说明性的名称,便于在测试报告中展示

在这里插入图片描述

6、@Disabled

  • 当执行所有测试方法时候,@Disabled注解的方法不会执行

在这里插入图片描述

7、@RepeatedTest

  • 用于多次重复执行某个测试,可以指定重复次数

在这里插入图片描述

四、常用断言

  断言(Assertions)在单元测试中用于验证程序行为是否符合预期。JUnit 提供了一组用于编写断言的方法,断言的使用可以帮助判断测试是否通过。类名org.junit.jupiter.api.Assertions

1、assertEquals(expected, actual)

  • 验证两个对象是否相等
  • 可以用于各种数据类型,包括基本类型、对象等
assertEquals(5, 2 + 3);
assertEquals("Hello", greetingService.getGreeting());

2、assertNotEquals(expected, actual)

  • 验证两个对象是否不相等
assertNotEquals(10, 2 + 3);

3、assertTrue(condition)

  • 验证条件为true
assertTrue(5 > 3);

4、assertFalse(condition)

  • 验证条件为false
assertFalse(3 > 5);

5、assertNull(actual)

  • 验证对象是否为null
String str = null;
assertNull(str);

6、assertNotNull(actual)

  • 验证对象是否不为null
String str = "Hello";
assertNotNull(str);

7、assertArrayEquals(expected, actual)

  • 验证两个数组是否相等
  • 数组的长度和元素的顺序都必须相同
int[] expected = {1, 2, 3};
int[] actual = {1, 2, 3};
assertArrayEquals(expected, actual);

8、assertSame(expected, actual)

  • 验证两个对象引用是否指向同一个对象(即是同一个对象的引用)
Object obj = new Object();
assertSame(obj, obj);

9、assertNotSame(expected, actual)

  • 验证两个对象引用是否不指向同一个对象
Object obj1 = new Object();
Object obj2 = new Object();
assertNotSame(obj1, obj2);

10、fail(message)

  • 强制使测试失败
  • 通常用于标记不应该被执行的代码路径
if (someCondition) {fail("Unexpected condition occurred");
}

11、带有消息参数的断言

  JUnit的断言方法通常有一个变体,可以带有一个额外的字符串参数,用于在测试失败时提供错误消息,帮助更快找到问题。

在这里插入图片描述

五、@MockBean注入

1、@MockBean的主要作用

  • @MockBean会将应用上下文中的某个Bean替换为模拟的Bean(Mock 对象)
  • @MockBean自动与Spring上下文集成,允许模拟的Bean被注入到需要它的其他Bean中

2、@MockBean的典型用法(模拟数据层)

  假设我们有一个UserService依赖于UserRepository,而我们在测试中不想使用真实的UserRepository,而是使用模拟对象

@Service
public class UserService {private final UserRepository userRepository;public UserService(UserRepository userRepository) {this.userRepository = userRepository;}public User getUserById(Long id) {return userRepository.findById(id);}
}
  • 使用@MockBean来模拟UserRepository
  • given方法模拟了userRepository.findById(1L) 方法的调用,并定义了当该方法被调用时,willReturn表示返回一个mockUser对象
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.BDDMockito.given;@SpringBootTest
public class UserServiceTest {@Autowiredprivate UserService userService;// 模拟 UserRepository,替换掉应用上下文中的实际 Bean@MockBeanprivate UserRepository userRepository;@Testvoid testGetUserById() {// 创建模拟数据User mockUser = new User(1L, "John Doe");// 使用 Mockito 的 BDD 风格方法设置模拟行为given(userRepository.findById(1L)).willReturn(mockUser);// 调用服务层方法,验证返回值是否符合预期User result = userService.getUserById(1L);assertEquals("John Doe", result.getName());}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/881698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC毕设项目分享:基于RAG的数字人对话系统及其应用

本研究的主要目标是设计并实现一个基于检索增强生成&#xff08;RAG&#xff09;技术的数字人对话系统&#xff0c;旨在提升数字人系统在多轮对话中的上下文管理、情境感知能力以及动态内容生成效果。系统结合了深度学习中的最新大语言模型技术&#xff0c;通过引入RAG框架来增…

K8S配置MySQL主从自动水平扩展

前提环境 操作系统Ubuntu 22.04 K8S 1.28.2集群&#xff08;1个master2个node&#xff09; MySQL 5.7.44部署在K8S的主从集群 metrics-server v0.6.4 概念简介 在K8s中扩缩容分为两种 ●Node层面&#xff1a;对K8s物理节点扩容和缩容&#xff0c;根据业务规模实现物理节点自动扩…

爬虫案例——网易新闻数据的爬取

案例需求&#xff1a; 1.爬取该新闻网站——&#xff08;网易新闻&#xff09;的数据&#xff0c;包括标题和链接 2.爬取所有数据&#xff08;翻页参数&#xff09; 3.利用jsonpath解析数据 分析&#xff1a; 该网站属于异步加载网站——直接网页中拿不到&#xff0c;需要…

MySQL-08.DDL-表结构操作-创建-案例

一.MySQL创建表的方式 1.首先根据需求文档定义出原型字段&#xff0c;即从需求文档中可以直接设计出来的字段 2.再在原型字段的基础上加上一些基础字段&#xff0c;构成整个表结构的设计 我们采用基于图形化界面的方式来创建表结构 二.案例 原型字段 各字段设计如下&…

深入理解线性表--顺序表

目录 顺序表- Seqlist -> sequence 顺序 list 表 顺序表的概念 问题与解答 顺序表的分类 静态顺序表 动态顺序表 问题与解答(递进式) 动态顺序表的实现 尾插 头插 尾删 头删 指定位置插入 指定位置删除 销毁 总结 前言&#xff1a;线性表是具有相同特性的一类数据结构…

2024 年 04 月编程语言排行榜,PHP 排名创新低?

编程语言的流行度总是变化莫测&#xff0c;每个月的排行榜都揭示着新的趋势。2024年4月的编程语言排行榜揭示了一个引人关注的现象&#xff1a;PHP的排名再次下滑&#xff0c;创下了历史新低。这种变化对于PHP开发者和整个技术社区来说&#xff0c;意味着什么呢&#xff1f; P…

现代数字信号处理I-P3 MVUE学习笔记

目录 1. 参数估计问题的提出与本质 2. 估计的性质 2.1 Ancillary&#xff08;多余估计&#xff09; 例1&#xff0c;Ancillary估计量 2. Uniformly Optimal 3. Sufficiency充分性 3.1 统计量充分性定义 例2&#xff1a;利用充分统计量定义获取伯努利分布的充分统计量 …

Anaroute - 理论学习(一)

一、贡献&#xff1a; 框架能够在考虑特定约束的同时&#xff0c;高效地完成复杂AMS设计的布线&#xff0c;并实现签署质量的性能。 提出了一种对称性约束的分配算法&#xff0c;根据引脚位置分配合适的网络匹配要求新的引脚聚类策略&#xff0c;以实现规律性的布线模式&…

微知-Bluefield DPU使用flint烧录固件报错MFE_NO_FLASH_DETECTED是什么?MFE是什么?

文章目录 背景一些报错场景MFE是什么&#xff1f;有哪些MFE 背景 在DPU的fw操作flint的时候&#xff0c;很多命令都会报这个错误&#xff1a;MFE_NO_FLASH_DETECTED&#xff0c;早期很疑惑并且猜测MFE是Mellanox Firmware Engine。实际并不是&#xff0c;具体还得走到mellanox…

2014年国赛高教杯数学建模B题创意平板折叠桌解题全过程文档及程序

2014年国赛高教杯数学建模 B题 创意平板折叠桌 某公司生产一种可折叠的桌子&#xff0c;桌面呈圆形&#xff0c;桌腿随着铰链的活动可以平摊成一张平板&#xff08;如图1-2所示&#xff09;。桌腿由若干根木条组成&#xff0c;分成两组&#xff0c;每组各用一根钢筋将木条连接…

2024 第一次周赛

A: 题目大意 骑士每连续 i 天每天会得到 i 个金币&#xff0c;&#xff08;i 1&#xff0c; 2&#xff0c; 3 &#xff0c; …&#xff09;,那么展开看每一天可以得到的金币数&#xff1a;1 2 2 3 3 3 4 4 4 5 5 5 5 5 … 可以发现就是1个1 &#xff0c;2个2, 3个3…,那么我…

php 生成随机数

记录:随机数抽奖 要求:每次生成3个 1 - 10 之间可重复(或不可重复)的随机数,10次为一轮,每轮要求数字5出现6次、数字4出现3次、…。 提炼需求: 1,可设置最小数、最大数、每次抽奖生成随机数的个数、是否允许重复 2,可设置每轮指定数字的出现次数 3,可设置每轮的抽奖…

一维数组的引用

#define SIZE 5 int main(void) { int i 0; int arr[SIZE] { 86,85,85,896,45 };//同理五个数据只是偶然&#xff0c;可能会更多 //输入 for (i 0;i < SIZE;i) { printf("请输入你的第%d个值&#xff1a;",i1); scanf_s(&…

Spark常用RDD算子:transformation转换算子以及action触发算子

文章目录 1. 算子&#xff08;方法&#xff09;介绍2. 常用transformation算子2.1 map 2.2 flatMap2.3 filter2.4 distinct2.6 groupBy2.7 sortBy()2.8 k-v数据[(k,v),(k1,v1)] 3. 常用action算子 1. 算子&#xff08;方法&#xff09;介绍 rdd中封装了各种算子方便进行计算&a…

【Linux网络编程】网络基础 | Socket 编程基础

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

【动手学深度学习】6.3 填充与步幅(个人向笔记)

卷积的输出形状取决于输入形状和卷积核的形状在应用连续的卷积后&#xff0c;我们最终得到的输出大小远小于输入大小&#xff0c;这是由于卷积核的宽度和高度通常大于1导致的比如&#xff0c;一个 240 240 240240 240240像素的图像&#xff0c;经过10层 5 5 55 55的卷积后&am…

自然语言处理问答系统:技术进展、应用与挑战

自然语言处理&#xff08;NLP&#xff09;问答系统是人工智能领域的一个重要分支&#xff0c;它通过理解和分析用户的提问&#xff0c;从大量的文本数据中提取相关信息&#xff0c;并以自然语言的形式回答用户的问题。随着深度学习技术的发展&#xff0c;尤其是预训练语言模型&…

MATLAB智能优化算法-学习笔记(4)——灰狼优化算法求解旅行商问题【过程+代码】

灰狼优化算法(Grey Wolf Optimizer, GWO)是一种基于灰狼社会行为的元启发式算法,主要模拟灰狼群体的捕猎行为(包括围攻、追捕、搜寻猎物等过程)。多旅行商问题(Multi-Traveling Salesman Problem, mTSP)是旅行商问题(TSP)的扩展,它涉及多个旅行商(车辆)从一个起点城…

深度学习:循环神经网络—RNN的原理

传统神经网络存在的问题&#xff1f; 无法训练出具有顺序的数据。模型搭建时没有考虑数据上下之间的关系。 RNN神经网络 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09;是一种专门用于处理序列数据的神经网络。在处理序列输入时具有记忆性…

动态规划的优化与高级应用

姊妹篇&#xff1a; 动态规划基础与经典问题-CSDN博客 贪心算法&#xff1a;原理、应用与优化_最优解-CSDN博客​​​​​​贪心算法&#xff1a;原理、应用与优化_最优解-CSDN博客 一、动态规划的优化策 动态规划在提高时间效率的同时&#xff0c;往往会占用较多的空间。因…