Spring boot如何执行单元测试?
Spring Boot 提供了丰富的测试功能,主要由以下两个模块组成:
spring-boot-test:提供测试核心功能。spring-boot-test-autoconfigure:提供对测试的自动配置。
Spring Boot 提供了一个 spring-boot-starter-test一站式启动器,如以下依赖配置所示。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
测试启动器依赖不仅包含以上两个 Spring Boot模块,还包含 Spring Test 测试模块,以及其他
第三方测试类库,如下所示。
- JUnit 5:Java 最主流的单元测试框架。
- AssertJ:一款快速断言库。
- Hamcrest:一款单元测试匹配库。
- Mockito:一款 Mock 测试框架。
- JSONassert:一款 JSON 断言库。
- JsonPath:一款 JSON XPath 库。
更多测试相关的依赖可见具体的依赖关系树,如下图所示。

以上这些都是 Spring Boot 提供的常用的测试类库,如果上面的测试类库还不能满足你的需要,也可以任意添加以上没有的类库。
现在基本上使用的是 JUnit 5,如果应用还在使用JUnit 4 写的单元测试用例,那么也可以使用JUnit 5 的 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>
需要排除 hamcrest-core 依赖,因为该依赖已经改坐标了,并且默认内置在Spring Boot依赖管理中,如上面的依赖关系树所示,最新的 Hamcrest依赖已经是org.hamcrest:hamcrest坐标了。
Spring Boot提供了一个 @SpringBootTest 注解,用在单元测试类上以启用支持Spring Boot特性的单元测试,如果使用的是JUnit 4,那么测试类上还需要额外的@RunWith(SpringRunner. class)注解,然后在测试类方法上添加 @Test 注解即可,每一个 @Test 注解修饰的方法就是一个单元测试方法。
@SpringBootTest 注解有一个最重要的 webEnvironment 环境参数,支持以下几种环境设置:
- MOCK(默认): 加载一个
Web ApplicationContext并提供一个Mock Web Environment,但不会启动内嵌的 Web 服务器,并可以结合@AutoConfifigureMockMvcor和@AutoConfifigure-WebTestClient注解一起使用进行 Mock 测试。 - RANDOM_PORT: 加载一个
WebServerApplicationContext,以及提供一个真实的WebEnvironment,并以随机端口启动内嵌服务器。 - DEFINED_PORT: 和
RANDOM_PORT一样,不同的是DEFINED_PORT是以应用指定的端口运行的,默认端口为 8080。 - NONE: 加载一个
ApplicationContext,但不会提供任何Web Environment。
如果使用的@SpringBootTest注解不带任何参数,则默认为 Mock 环境。
真实环境测试
在 @SpringBootTest 注解中指定基于随机端口的真实Web环境,然后在类成员变量或者方法参数上注入 TestRestTemplate 实例,就可以完成对 Spring MVC接口的真实环境测试。
下面是一个基于随机端口的真实环境的测试用例:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MvcTest {@Testpublic void getUserTest(@Autowired TestRestTemplate testRestTemplate) {Map<String, String> multiValueMap = new HashMap<>();multiValueMap.put("username", "Java 技术栈 ");Result result = testRestTemplate.getForObject("/user/get?username={username}",Result.class, multiValueMap);assertThat(result.getCode()).isEqualTo(0);assertThat(result.getMsg()).isEqualTo("ok");}}
测试当前应用下的 /user/get 接口,传入对应的用户名参数,最后检查接口返回结果是否和预期一致,测试结果如下图所示。

单元测试通过,从执行日志可以看到,它启动了一个嵌入式的 Tomcat 容器来测试真实的 Web应用环境。
Mock 环境测试
通过在类上面使用 @AutoConfifigureMockMvc 注解,然后在类成员变量或者方法参数上注入MockMvc 实例,就可以完成对 Spring MVC 接口的 Mock 测试。
下面是一个基于默认 Mock 环境的测试用例:
@SpringBootTest
@AutoConfigureMockMvc
class MockMvcTests {@Testpublic void getUserTest(@Autowired MockMvc mvc) throws Exception {mvc.perform(MockMvcRequestBuilders.get("/user/get?username={username}", "test")).andExpect(status().isOk()).andExpect(content().string("{\"code\":0,\"msg\":\"ok\",\"
data\":\"test\"}"));}
}
测试当前应用下的 /user/get 接口,传入对应的用户名参数,最后检查请求状态是否OK(200),响应的内容是否和预期一致,测试结果如下图所示。

单元测试通过,从执行日志可以看到,它并未启动真实的 Web 环境来测试,而是使用 Mock 环境测试的。
Mock 组件测试
某些时候可能还需要模拟一些组件,比如某些服务只有上线之后才能调用,在开发阶段不可用,这时就需要 Mock 模拟测试了,提供各种模拟组件以完成测试。
Spring Boot 提供了一个 @MockBean 注解,可为 Spring 中的 Bean 组件定义基于 Mockito 的Mock 测试,它可以创建一个新 Bean 以覆盖 Spring 环境中已有的 Bean,它可以用在测试类、成员变量上,或者 @Confifiguration 配置类、成员变量上,被模拟的 Bean 在每次测试结束后自动重置。
假现现在有一个远程的服务 userService,本地不能调用,现在进行 Mock 测试,如以下使用示例所示。
@SpringBootTest
class MockBeanTests {
// @Autowired
// private UserService userService;@MockBeanprivate UserService userService;@Testpublic void countAllUsers() {BDDMockito.given(this.userService.countAllUsers()).willReturn(88);assertThat(this.userService.countAllUsers()).isEqualTo(88);}
}
这里的 @MockBean 注解使用在 UserService 变量上,表明这个userService实例在当前测试用例中是被 Mock 覆盖的,如果要模拟的 Bean 有多个,则可以使用@Qualififier注解指定,然后通过Mockito 提供的代理工具类方法创建模拟返回数据,运行该服务的测试方法,当模拟数据和预期结果一致时才会测试通过。
这里通过 BDDMockito 工具类模拟 userService#countAllUsers方法并让它返回统计的用户总数(88),最后检查该方法的返回值是否和预期一致,测试结果如下图所示。

单元测试通过,也可以使用 @SpyBean 注解代替 @MockBean 注解,两者的区别是:
@SpyBean—如果没有提供 Mockito 代理方法,则会调用真实的 Bean 来获取数据。@MockBean—不管有没有提供 Mockito 代理方法,都会调用 Mock 的 Bean 来获取数据。
@MockBean、@SpyBean注解既可作用于 Mock 环境,也可作用于真实环境,它只是用来模拟、替换环境中指定的 Bean 而已,但不能用于模拟在应用上下文刷新期间 Bean 的行为,因为在执行测试用例时应用上下文已经刷新完成了,所以不可能再去模拟了,这种情况下建议使用@Bean方法来创建模拟配置。
相关文章:
Spring boot如何执行单元测试?
Spring Boot 提供了丰富的测试功能,主要由以下两个模块组成: spring-boot-test:提供测试核心功能。spring-boot-test-autoconfigure:提供对测试的自动配置。 Spring Boot 提供了一个 spring-boot-starter-test一站式启动器&…...
Django详细教程(一) - 基本操作
文章目录 前言一、安装Django二、创建项目1.终端创建项目2.Pycharm创建项目(专业版才可以)3.默认文件介绍 三、创建app1.app介绍2.默认文件介绍 四、快速上手1.写一个网页步骤1:注册app 【settings.py】步骤2:编写URL和视图函数对…...
Qt编译QScintilla(C++版)过程记录,报错-lqscintilla2_qt5d、libqscintilla2_qt5找不到问题解决
Qt编译QScintilla [C版] 过程记录 本文是编译该 QScintilla 组件库供 QtCreater 开发 C 桌面软件 流程记录一、编译环境 系统: Windows 10Qt:Qt 5.14.2编译套件:MinGW 64Qscintilla:QScintilla_src-2.11.6 二、下载链接 网站链…...
android QtScrcpy 共享屏幕 获取本地Address
android QtScrcpy https://gitee.com/B arryda/QtScrcpy scrcpy - 手机无线投屏到电脑 https://zhuanlan.zhihu.com/p/80264357?utm_sourcewechat_session public String getLocalIpAddress() { String ipv4; List<NetworkInterface> nilist …...
【SQL Server】1. 认识+使用
1. 创建数据库的默认存储路径 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft SQL Server 2008 R2 当我们选择删除数据库时,对应路径下的文件也就删除了 2. 导入导出数据工具的路径 3. 注册数据库遇到的问题 ??? 目前的问题就是服务器新建…...
视频汇聚/安防监控/视频存储EasyCVR平台EasyPlayer播放器更新:新增【性能面板】
视频汇聚/安防监控/视频存储平台EasyCVR基于云边端架构,可以在复杂的网络环境中快速、灵活部署,平台视频能力丰富,可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云…...
图神经网络实战(7)——图卷积网络(Graph Convolutional Network, GCN)详解与实现
图神经网络实战(7)——图卷积网络详解与实现 0. 前言1. 图卷积层2. 比较 GCN 和 GNN2.1 数据集分析2.2 实现 GCN 架构 小结系列链接 0. 前言 图卷积网络 (Graph Convolutional Network, GCN) 架构由 Kipf 和 Welling 于 2017 年提出,其理念是…...
大话设计模式之外观模式
外观模式(Facade Pattern)是一种软件设计模式,旨在提供一个简单的接口,隐藏系统复杂性,使得客户端能够更容易地使用系统。这种模式属于结构型模式,它通过为多个子系统提供一个统一的接口,简化了…...
CAD Plant3D 2024 下载地址及安装教程
CAD Plant3D是一款专业的三维工厂设计软件,用于在工业设备和管道设计领域进行建模和绘图。它是Autodesk公司旗下的AutoCAD系列产品之一,专门针对工艺、石油、化工、电力等行业的设计和工程项目。 CAD Plant3D提供了一套丰富的工具和功能,帮助…...
Intellij IDEA / Android studio 可持续开发笔记
Intellij 的Java/安卓工具链有着一种不可持续性,这种不可持续性体现在多个方面。 首先是不可持续运行。IDEA 使用时间越长,内存占用越大,从不主动释放。运行时间越长,日志越多,从不主动清理。 然后是不完整的开源&am…...
c++----list模拟实现
目录 1. list的基本介绍 2. list的基本使用 2.1 list的构造 用法示例 2.2 list迭代器 用法示例 2.3. list容量(capacity)与访问(access) 用法示例 2.4 list modifiers 用法示例 2.5 list的迭代器失效 3.list的模拟实现 3.1…...
FastAPI+React全栈开发15 让我们构建一个展示API
Chapter03 Getting Started with FastAPI 15 Let’s Build a showcase API FastAPIReact全栈开发15 让我们构建一个展示API REST APIs are all about cycles of HTTP requests and responses, it is the engine that powers the web and is implemented in every web framew…...
list(链表)容器(二)
一、list 插入和删除 函数原型: push_back(elem);//在容器尾部加入一个元素 pop_back();//删除容器中最后一个元素 push_front(elem);//在容器开头插入一个元素 pop_front();//从容器开头移除第一个元素 insert(pos,elem);//在pos位置插elem元素的拷贝,…...
世优科技上榜2024年度《中国虚拟数字人影响力指数报告》
日前,第三期《中国虚拟数字人影响力指数报告》在中国网络视听大会上正式发布。本期《报告》由中国传媒大学媒体融合与传播国家重点实验室(以下简称“国重实验室”)、中国传媒大学数字人研究院编制,中国网络视听协会、人民日报智慧…...
【调试方法】C代码中dump中间数据的方法
一,简介 本文主要介绍,如何在C语言代码中将音频流数据进行写入文件,方便调试定位问题: 二,函数实现 按int8_t写入 #include <stdio.h>int32_t write_int8_t_data(int8_t *name, int8_t *buffer, int32_t dat…...
【BUG】vue中@change时间传值丢失问题
项目场景: 在修改项目bug时,发现后端响应到前端的值,通过change事件调用方法,在方法中拿到值时,有部分数据丢失。 问题描述 后端传到前端的值为:字符串类型的"00000089",change调用…...
Linux提权!!!
上一篇文章讲了Windows的提权,那么这篇文章就来讲一下Linux的提权 1.SUID提权 suid权限 作用:让普通用户临时拥有该文件的属主的执行权限,suid权限只能应用在二进制可执行文件(命令)上,而且suid权限只能设置…...
Android Studio学习7——常用控件view
Android控件 双击shift键——>搜索想要找的文件 Ctrlshift回车——>补全“;”号 CtrlX——>删除一行,只需把鼠标放在那一行 windows自带字体...
Springboot3 集成knife4j(swagger)
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍! 官网地址: Knife4j 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j 本文以Springboot3版本集成kn…...
深信服:借助观测云实现全链路可观测性
导读 深信服科技股份有限公司 简称「深信服」( Sangfor Technologies Inc. ),是一家领先的网络安全和云计算解决方案提供商,致力于为全球客户提供高效、智能、安全的网络和云服务。随着公司业务的不断扩展,也面临着监…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
