项目测试之MockMvc
文章目录
- 基础
- 基础概念
- Mockxxx
- 一般实现
- 文件位置
- 实战
- MockMvc与Test注解不兼容
- @RequestParams参数
- @RequestBody参数
基础
基础概念
定义:是Spring框架提供的一种用于测试Spring MVC控制器的工具,它允许开发者在不启动完整的web服务器的情况下,模拟HTTP请求并验证响应。优点:执行速度快 --》 不需要启动web服务器;便于集成 --》 可以与Junit、TestNG等测试框架无缝衔接;强大的功能 --》 对HTTP请求的详细配置和响应的全面验证;依赖配置:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
Mockxxx
MockMvc:来自于:import org.springframework.test.web.servlet.MockMvc;定义:是Spring Test模块的一部分,它允许开发者对Spring MVC控制器进行单元测试而无需启动完整的Web服务器;通过MockMvc,可以模拟HTTP请求并验证响应,使得测试执行速度更快,同时便于与JUnit、TestNG等测试框架集成。使用:使用mockMvc。perform()模拟HTTP请求,使用.andExpect()和.andReturn()等方法进行响应验证。
Mockito:来自于:import org.mockito.Mockito;定义:流行的Java单元测试框架,专门用于创建和验证模拟对象的行为。它允许开发者在编写测试时模拟外部依赖,从而使得测试更便捷,减少对外部类、系统和依赖给单元测试带来的耦合。特点:行为验证、测试桩、参数匹配器、注册支持、监控真实对象、重置mock对象;
MvcResult:来自于:import org.springframework.test.web.servlet.MvcResult;定义:是在执行模拟HTTP请求以测试控制器(Controller)层功能时的重要概念,它代表一个完整的HTTP响应结果,包括响应的状态码、头信息、响应体以及任何可能产生的错误等。作用:封装HTTP响应 -》封装由模拟的HTTP产生的完整响应信息;获取响应细节 -》包括响应的状态码、头信息、响应体等内容;断言测试 -》 使用MvcResult中的方法进行断言,确保控制器返回正确的HTTP状态码和数据;
一般实现
// 类注解,用于配置 JUnit 5 测试类以使用 Spring 的测试支持。
@ExtendWith(SpringExtension.class)// 是一个 Spring Boot 提供的注解,用于对 Web 层(即控制器层)进行测试。如果使用该注解,那么Spring Boot 会自动配置一个模拟的 Spring MVC 环境,这样就可以在不启动完整应用的情况下测试控制器的行为。
@WebMvcTest(value = {Controller.class, Handler.class})// 完成bean自动装配
@Autowired
private MockMvc mockMvc;// 标识测试方法
@Test
MockHttpServletRequestBuilder requestBuilder = get("控制类路径/xxx/xxx");
// MockHttpServletRequestBuilder 是一个用于构建模拟HTTP请求的工具类。
// 主要在单元测试和集成测试中使用,构造出特定的HTTP请求来测试控制器(Controller)或端点(Endpoint)。
requestBuilder.param("参数名", 参数值);
// 给已创建的mockhttpservletrequestbuilder实例添加查询参数;
// 将参数通过键值对的形式填入MockHttpServletRequestBuilder对象中;mockMvc.perform(requestBuilder) // mockMvc对象执行,之前定义的requestbuiler对象.andExpect(status().isOk()) // 该调用方式是链式调用;--》 用于检查HTTP响应的状态码是否是200.andDo(new ResultHandler() { // 自定义处理MvcResult对象,即模拟请求后的结果@Overridepublic void handle(MvcResult mvcResult) throws Exception {// 获取响应体并将其转化为字符串类型;String content = mvcResult.getResponse().getContentAsString();// 检查响应体是否为空,以确保有数据返回;assertTrue(StringUtils.isNotBlank(content));// 将响应体内容解析成map集合Map<String, String> resp = JSONUtils.toMap(content);// 验证code/message 两个属性的值是否等于1/success;assertEquals("1", resp.get("code"));assertEquals("success", resp.get("message"));// 获取data属性对应的值String data = resp.get("data");// base64解码byte[] encryptedData = Base64.decode(data);// aes密钥生成AES aes = genAES(keyIv);// 解密data对应的值String json = new String(aes.decrypt(encryptedData), StandardCharsets.UTF_8);// json format is ResponseKeyCollection 自定义的一个类ResponseKeyCollection collection = JSONUtils.toObject(json, ResponseKeyCollection.class);// 将json转成 ResponseKeyCollection对象assertEquals(10, collection.getResponseKeys().size());// 验证对象中getResponseKeys方法返回的集合大小是否为10}});@BeforeEach
ResponseKey responseKey1 = COLLECTION.getResponseKeys().stream().filter(key -> key.getIndex() == 1).findFirst().orElse(null);
// COLLECTION获取ResponseKeys属性--》转换为流--》过滤出index=1的responseKey对象
// --》查找第一个满足条件的--》有则返回,无则返回null;
// COLLECTION 是自定义的对象
Mockito.when(keyStoreService.getResponseKey(1)).thenReturn(responseKey1);
// 模拟该方法,当此入参为1时,则返回上述找到的对象;
Mockito.when(keyStoreService.generateResponseKeyCollection(10)).thenReturn(COLLECTION);
// 模拟该方法,当此入参为10时,则返回Collecion对象;
Mockito.when(keyHelper.isExpiredKeyIndex(anyInt())).thenReturn(false);
// 模拟此方法,不管该方法入参为谁,都返回false --》 即keyIndex永不过期
文件位置
与项目目录保持一致;
假设项目文件为src/main/java/xxx/controller/xxxController
测试类项目文件为src/test/java/xxx/controller/xxxTest
实战
MockMvc与Test注解不兼容
参考博客:https://segmentfault.com/q/1010000042943340
描述:使用 @Autowiredprivate MockMvc mockMvc;总是导致注入的mockMvc失败;
原因是:MockMvc与@Test不兼容的问题;原本依赖库为:org.junit.Test 改成org.junit.jupiter.api.Test 就可以了;两个依赖库之间的关系为:org.junit.Test --》 JUnit4 org.junit.jupiter.api.Test --》 JUnit5
@RequestParams参数
MockHttpServletRequestBuilder requestBuilder = get("/decrypt");
requestBuilder.param("id1", id1);
requestBuilder.param("id2", id2);
mockMvc.perform(requestBuilder).andExpect(status().isOk()).andDo(mvcResult -> {String content = mvcResult.getResponse().getContentAsString();
});
@RequestBody参数
接口请求参数:
@RequestMapping("/getfunction1")
public ResultDtoRisk riskGetTokenByph(HttpServletRequest request, @RequestBody NumReq numReq){}测试代码:
@Autowired
pivate MockMvc mockMvc;
// import org.springframework.test.web.servlet.MockMvc;NumReq numReq = new NumReq();
numReq.setId1(id1);
numReq.setId2(id2);MockHttpServletRequestBuilder requestBuilder = get("/getfunction1");
// import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
String requestBodyContent = objectMapper.writeValueAsString(numReq);requestBuilder.contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBodyContent);mockMvc.perform(requestBuilder).andExpect(status().isOk()).andDo(print());
相关文章:
项目测试之MockMvc
文章目录 基础基础概念Mockxxx一般实现文件位置 实战MockMvc与Test注解不兼容RequestParams参数RequestBody参数 基础 基础概念 定义:是Spring框架提供的一种用于测试Spring MVC控制器的工具,它允许开发者在不启动完整的web服务器的情况下,…...
网易Android开发面试题200道及参考答案 (下)
说明原码、反码、补码的概念 原码:是一种简单的机器数表示法。对于有符号数,最高位为符号位,0 表示正数,1 表示负数,其余位表示数值的绝对值。比如,对于 8 位二进制数,+5 的原码是 00000101,-5 的原码是 10000101。原码的优点是直观,容易理解,但在进行加减法运算时,…...
PHP根据IP地址获取地理位置城市和经纬度信息
/** 根据IP地址 获取地理位置*/ function getLocationByIP($ip) {$url "http://ip-api.com/json/{$ip}?langzh-CN&fieldsstatus,message,country,countryCode,region,regionName,city,lat,lon,timezone,isp,org,as";$response file_get_contents($url);$data …...
AI Agent的多轮对话:提升用户体验的关键技巧
在前面的文章中,我们讨论了 AI Agent 的各个核心系统。今天,我想聊聊如何实现一个好用的多轮对话系统。说实话,这个话题我琢磨了很久,因为它直接影响到用户体验。 从一个槽点说起 还记得我最开始做对话系统时的一个典型场景&…...
在docker上部署nacos
一、首先下载nacos的docker镜像 docker pull nacos:2.5.0 二、然后下载nacos的安装包,这里是为了拿到他的配置文件。下载完解压缩后,以备后用 https://download.nacos.io/nacos-server/nacos-server-2.5.0.zip?spm5238cd80.6a33be36.0.0.2eb81e5d7mQ…...
ComfyUI实现老照片修复——AI修复老照片(ComfyUI-ReActor / ReSwapper)解决天坑问题及加速pip下载
AI修复老照片,试试吧,不一定好~~哈哈 2023年4月曾用过ComfyUI,当时就感慨这个工具和虚幻的蓝图很像,以后肯定是专业人玩的。 2024年我写代码去了,AI做图没太关注,没想到,现在ComfyUI真的变成了工…...
Win11画图工具没了怎么重新安装
有些朋友想要简单地把图片另存为其他格式,或是进行一些编辑,但是发现自己的Win11系统里面没有画图工具,这可能是因为用户安装的是精简版的Win11系统,解决方法自然是重新安装一下画图工具,具体应该怎么做呢?…...
Git Bash 配置 zsh
博客食用更佳 博客链接 安装 zsh 安装 Zsh 安装 Oh-my-zsh github仓库 sh -c "$(curl -fsSL https://install.ohmyz.sh/)"让 zsh 成为 git bash 默认终端 vi ~/.bashrc写入: if [ -t 1 ]; thenexec zsh fisource ~/.bashrc再重启即可。 更换主题 …...
《STL基础之hashtable》
【hashtable导读】STL为大家提供了丰富的容器,hashtable也是值得大家学习和掌握的基础容器,而且面试官经常会把它和hashmap混在一起,让同学们做下区分。因此关于hashtable的一些特性,比如:底层的数据结构、插入、查找元…...
Vue3组件重构实战:从Geeker-Admin拆解DataTable的最佳实践
一、前言 背景与动机 在当前的开发实践中,我们选择了开源项目 Geeker-Admin 作为前端框架的二次开发基础。其内置的 ProTable.vue 组件虽然提供了一定程度的开箱即用性,但在实际业务场景中逐渐暴露出设计上的局限性,尤其是其将 搜索条件表单…...
小智 AI 聊天机器人
小智 AI 聊天机器人 (XiaoZhi AI Chatbot) 👉参考源项目复现 👉 ESP32SenseVoiceQwen72B打造你的AI聊天伴侣!【bilibili】 👉 手工打造你的 AI 女友,新手入门教程【bilibili】 项目目的 本…...
关于圆周率的新认知
从自然对数底 的泰勒展开, 可以得出 的展开式, 它可以被认为是,以 0 为周期的单位 1 ,以 1 为周期的单位 1 ,以 2 为周期的单位 1 等所有自然数为周期的单位 1 分阶段合成(体现为阶乘的倒数)之…...
【趋势】《2024—2026金融科技十大趋势预测》一览
本白皮书基于新华三在金融行业的前沿实践和IDC的全球研究成果,深入分析了金融科技领域的十大关键趋势,旨在为金融机构提供前瞻性的战略指导和业务创新的参考。 导言 当前,在地缘政治冲突加剧、商业经济市场环境高度不确定、数字化业务加速发展的背景下,金融行业处于深度变…...
vim 中粘贴内容时提示: -- (insert) VISUAL --
目录 问题现象:解决方法:问题原因: 问题现象: 使用 vim 打开一个文本文件,切换到编辑模式后,复制内容进行粘贴时有以下提示: 解决方法: 在命令行模式下禁用鼠标支持 :set mouse …...
CAPL高级应用
CAPL高级应用 目录 CAPL高级应用1. 引言2. 多线程编程2.1 多线程编程简介2.2 多线程编程实现3. 数据库操作3.1 数据库操作简介3.2 数据库操作实现4. 网络通信4.1 网络通信简介4.2 网络通信实现5. 案例说明5.1 案例1:多线程编程实现5.2 案例2:数据库操作实现5.3 案例3:网络通…...
基于微信小程序的网上订餐管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
python的设计模式
设计模式是解决软件设计中常见问题的可重用解决方案。Python 作为一种灵活且强大的编程语言,支持多种设计模式的实现。以下是 Python 中常见的几种设计模式及其示例: 1. 单例模式(Singleton Pattern) 确保一个类只有一个实例&…...
EventBus事件总线的使用以及优缺点
EventBus EventBus (事件总线)是一种组件通信方法,基于发布/订阅模式,能够实现业务代码解耦,提高开发效率 发布/订阅模式 发布/订阅模式是一种设计模式,当一个对象的状态发生变化时,所有依赖…...
C++解决走迷宫问题:DFS、BFS算法应用
文章目录 思路:DFSBFSBFS和DFS的特点BFS 与 DFS 的区别BFS 的优点BFS 时间复杂度深度优先搜索(DFS)的优点深度优先搜索(DFS)的时间复杂度解释:空间复杂度总结:例如下面的迷宫: // 迷宫的表示:0表示可以走,1表示障碍 vector<vector<int>> maze = {{0, 0,…...
2025春招 SpringCloud 面试题汇总
大家好,我是 V 哥。SpringCloud 在面试中属于重灾区,不仅是基础概念、组件细节,还有高级特性、性能优化,关键是项目实践经验的解决方案,都是需要掌握的内容,正所谓打有准备的仗,秒杀面试官&…...
PostGIS笔记:PostgreSQL 数据库与用户 基础操作
数据库基础操作包括数据模型的实现、添加数据、查询数据、视图应用、创建日志规则等。我这里是在Ubuntu系统学习的数据库管理。Windows平台与Linux平台在命令上几乎无差异,只是说在 Windows 上虽然也能运行良好,但在性能、稳定性、功能扩展等方面&#x…...
Selenium配合Cookies实现网页免登录
文章目录 前言1 方案一:使用Chrome用户数据目录2 方案二:手动获取并保存Cookies,后续使用保存的Cookies3 注意事项 前言 在进行使用Selenium进行爬虫、网页自动化操作时,登录往往是一个必须解决的问题,但是Selenium每次…...
HarmonyOS简介:HarmonyOS核心技术理念
核心理念 一次开发、多端部署可分可合、自由流转统一生态、原生智能 一次开发、多端部署 可分可合 自由流转 自由流转可分为跨端迁移和多端协同两种情况 统一生态 支持业界主流跨平台开发框架,通过多层次的开放能力提供统一接入标准,实现三方框架快速…...
Unity URP 获取/设置 Light-Indirect Multiplier
Unity URP 获取/设置 Light-Indirect Multiplier 他喵的代码的字段名称叫:bounceIntensity ~~~~~~...
计算机网络 (60)蜂窝移动通信网
一、定义与原理 蜂窝移动通信网是指将一个服务区分为若干蜂窝状相邻小区并采用频率空间复用技术的移动通信网。其原理在于,将移动通信服务区划分成许多以正六边形为基本几何图形的覆盖区域,称为蜂窝小区。每个小区设置一个基站,负责本小区内移…...
解决.NET程序通过网盘传到Linux和macOS不能运行的问题
问题描述:.net程序用U盘传到虚拟机macOS和Linux可以正常运行,但是网盘传过去就不行。 解决方法: 这是文件权限的问题。当你通过U盘将文件传输到虚拟机的macOS和Linux系统时,文件的权限和所有权可能得到了保留或正确设置。但如果…...
LeetCode | 不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 示例 1…...
渗透测试技法之口令安全
一、口令安全威胁 口令泄露途径 代码与文件存储不当:在软件开发和系统维护过程中,开发者可能会将口令以明文形式存储在代码文件、配置文件或注释中。例如,在开源代码托管平台 GitHub 上,一些开发者由于疏忽,将包含数据…...
【C语言】main函数解析
一、前言 在学习编程的过程中,我们很早就接触到了main函数。在Linux系统中,当你运行一个可执行文件(例如 ./a.out)时,如果需要传入参数,就需要了解main函数的用法。本文将详细解析main函数的参数ÿ…...
Vue3笔记——(二)
015 生命周期 组件的生命周期: 【时刻】 【调用特定的函数】 vue2生命周期 创建 beforeCreate、 created 挂载 beforeMounte、mounted 更新 beforeUpdate、updated 销毁 beforeDestroy、destroyed 生命周期、生命周期函数、生命周期钩子 vue3生命周期 创建 setup 挂…...
linux文件I/O
open 用于打开一个文件并返回一个文件描述符。文件描述符是一个整数,它在后续的文件操作中用于标识文件。 原型: int open(const char *pathname, int flags, mode_t mode);pathname:要打开的文件的路径flags:指定文件打开方式…...
利用双指针一次遍历实现”找到“并”删除“单链表倒数第K个节点(力扣题目为例)
Problem: 19. 删除链表的倒数第 N 个结点 文章目录 题目描述思路复杂度Code 题目描述 思路 1.欲找到倒数第k个节点,即是找到正数的第n-k1、其中n为单链表中节点的个数个节点。 2.为实现只遍历一次单链表,我们先可以使一个指针p1指向链表头部再让其先走k步…...
MySQL 8 不开通 CLONE 插件,建立主从关系
文章目录 前言一、主库操作二、从库操作三、主库操作四、测试总结 前言 MySQL 版本:8.0.36 MySQL 8 通过 CLONE 插件,搭建主从数据库详情参考链接文章 主库不开通 CLONE 插件,如何建立主从关系呢?本文简单介绍一下 一、主库操作…...
活动回顾和预告|微软开发者社区 Code Without Barriers 上海站首场活动成功举办!
Code Without Barriers 上海活动回顾 Code Without Barriers:AI & DATA 深入探索人工智能与数据如何变革行业 2025年1月16日,微软开发者社区 Code Without Barriers (CWB)携手 She Rewires 她原力在大中华区的首场活动“AI &…...
Direct Preference Optimization (DPO): 一种无需强化学习的语言模型偏好优化方法
论文地址:https://arxiv.org/pdf/2305.18290 1. 背景与挑战 近年来,大规模无监督语言模型(LM)在知识获取和推理能力方面取得了显著进展,但如何精确控制其行为仍是一个难题。 现有的方法通常通过**强化学习从人类反馈&…...
搜狐Android开发(安卓)面试题及参考答案
ViewModel 的作用及原理是什么? ViewModel 是 Android 架构组件中的一部分,主要作用是在 MVVM 架构中充当数据与视图之间的桥梁。它负责为视图准备数据,并处理与数据相关的业务逻辑,让视图(Activity、Fragment 等)专注于展示数据和与用户交互。比如在一个新闻应用中,Vie…...
蓝牙的一些基础知识(TODO)
前阵工作中遇到的。 iOS 和 iPadOS 支持的蓝牙描述文件 - 官方 Apple 支持 (中国) 在树莓派上定制蓝牙 Profile 通常需要修改或创建自定义的 Bluetooth 服务 (Profile) 来实现特定的功能,例如定制 Audio Sink、HID(Human Interface Device)、…...
Redis实战(黑马点评)——涉及session、redis存储验证码,双拦截器处理请求
项目整体介绍 数据库表介绍 基于session的短信验证码登录与注册 controller层 // 获取验证码PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {return userService.sendCode(phone, session);}// 获…...
WPF常见面试题解答
以下是WPF(Windows Presentation Foundation)面试中常见的问题及解答,涵盖基础概念、高级功能和实际应用,帮助你更好地准备面试: 基础概念 什么是WPF? WPF是微软开发的用于构建桌面应用程序的UI框架&#x…...
Nginx前端后端共用一个域名如何配置
在 Nginx 中配置前端和后端共用一个域名的情况,通常是通过路径或子路径将请求转发到不同的服务。以下是一个示例配置,假设: 前端静态文件在 /var/www/frontend/。 后端 API 服务运行在 http://127.0.0.1:5000。 域名是 example.comÿ…...
DeepSeek-R1-Distill-Qwen-1.5B:最佳小型LLM?
DeepSeek掀起了生成式AI领域的风暴。 首先推出DeepSeek-v3,现在推出DeepSeek-R1,这两款模型都打破了所有基准,并且完全开源。 但今天我们不是在讨论这两款超级模型,而是讨论DeepSeek-R1的一个蒸馏版本——DeepSeek-R1-Distill-Qwen-1.5B,它可能是今天被低估的版本,虽然…...
wampserver + phpstrom 调试配置
step 1 点击任务栏wampserver图标->php->php.ini[apache module] 在文件最后面,确保这些值被定义且跟以下的一样 xdebug.mode debug xdebug.start_with_request yes xdebug.client_port 9003 xdebug.client_host 127.0.0.1step 2 按如下配置 step3 下断点,运行即…...
MySQL分表自动化创建的实现方案(存储过程、事件调度器)
《MySQL 新年度自动分表创建项目方案》 一、项目目的 在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低。分表是一种有效的优化策略,它将数据分散存储在多…...
RabbitMQ 架构分析
文章目录 前言一、RabbitMQ架构分析1、Broker2、Vhost3、Producer4、Messages5、Connections6、Channel7、Exchange7、Queue8、Consumer 二、消息路由机制1、Direct Exchange2、Topic Exchange3、Fanout Exchange4、Headers Exchange5、notice5.1、备用交换机(Alter…...
Spring Boot 无缝集成SpringAI的函数调用模块
这是一个 完整的 Spring AI 函数调用实例,涵盖从函数定义、注册到实际调用的全流程,以「天气查询」功能为例,结合代码详细说明: 1. 环境准备 1.1 添加依赖 <!-- Spring AI OpenAI --> <dependency><groupId>o…...
如何跨互联网adb连接到远程手机-蓝牙电话集中维护
如何跨互联网adb连接到远程手机-蓝牙电话集中维护 --ADB连接专题 一、前言 随便找一个手机,安装一个App并简单设置一下,就可以跨互联网的ADB连接到这个手机,从而远程操控这个手机做各种操作。你敢相信吗?而这正是本篇想要描述的…...
MySQL--》深度解析InnoDB引擎的存储与事务机制
目录 InnoDB架构 事务原理 MVCC InnoDB架构 从MySQL5.5版本开始默认使用InnoDB存储引擎,它擅长进行事务处理,具有崩溃恢复的特性,在日常开发中使用非常广泛,其逻辑存储结构图如下所示, 下面是InnoDB架构图…...
python:taichi 模拟一维波场
在 Taichi 中模拟一维波场,通常是利用 Taichi 编程语言的特性来对一维空间中的波动现象进行数值模拟,以下是相关介绍: 原理基础 波动方程:一维波动方程的一般形式为 ,其中 u(x,t) 表示在位置x 和时间t 处的波的状态&…...
力扣【347. 前 K 个高频元素】Java题解(堆)
TopK问题,我们直接上堆。 首先遍历一次然后把各个数字的出现频率存放在哈希表中便于后面堆的操作。 因为是出现频率前 k 高,所以用小顶堆,当我们遍历的频率值大于堆顶值时就可以替换堆顶。 代码: class Solution {public int[] …...
仿12306项目选座购票业务逻辑
12306项目选座购票业务逻辑 文章目录 12306项目选座购票业务逻辑项目分享选座逻辑购票逻辑更新余票逻辑用户选座功能服务器售票功能0. 业务数据校验1. 保存确认订单表,状态初始化2. 查出余票记录,需要得到真是的库存3. 扣减余票数量,并判断余…...