项目测试之MockMvc

文章目录

  • 基础
    • 基础概念
    • Mockxxx
    • 一般实现
    • 文件位置
  • 实战
    • MockMvc与Test注解不兼容
    • @RequestParams参数
    • @RequestBody参数

基础

基础概念

定义:是Spring框架提供的一种用于测试Spring MVC控制器的工具,它允许开发者在不启动完整的web服务器的情况下,模拟HTTP请求并验证响应。优点:执行速度快 --》 不需要启动web服务器;便于集成 --》 可以与JunitTestNG等测试框架无缝衔接;强大的功能 --》  对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请求并验证响应,使得测试执行速度更快,同时便于与JUnitTestNG等测试框架集成。使用:使用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());

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

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

相关文章

(详细)Springboot 整合动态多数据源 这里有mysql(分为master 和 slave) 和oracle,根据不同路径适配不同数据源

文章目录 Springboot 整合多动态数据源 这里有mysql&#xff08;分为master 和 slave&#xff09; 和oracle1. 引入相关的依赖2. 创建相关配置文件3. 在相关目录下进行编码&#xff0c;不同路径会使用不同数据源 Springboot 整合多动态数据源 这里有mysql&#xff08;分为maste…

计算机网络之计算机网络的分类

计算机网络可以根据不同的角度进行分类&#xff0c;以下是几种常见的分类方式&#xff1a; 1. 按照规模和范围&#xff1a; 局域网&#xff08;LAN&#xff0c;Local Area Network&#xff09;&#xff1a;覆盖较小范围&#xff08;例如一个建筑物或校园&#xff09;&#xf…

腾讯云开发提供免费GPU服务

https://ide.cloud.tencent.com/dashboard/web 适用于推理场景&#xff0c;每个月10000分钟免费时长 166 小时 40 分钟 自带学术加速&#xff0c;速度还是不错的 白嫖 Tesla T4 16G 算力 显存&#xff1a;16GB 算力&#xff1a;8 TFlops SP CPU&#xff1a;8 核 内存&#…

国内外大语言模型领域发展现状与预期

在数字化浪潮中&#xff0c;大语言模型已成为人工智能领域的关键力量&#xff0c;深刻影响着各个行业的发展轨迹。下面我们将深入探讨国内外大语言模型领域的发展现状以及未来预期。 一、发展现状 &#xff08;一&#xff09;国外进展 美国的引领地位&#xff1a;OpenAI 的 …

存储过程优化实践:统一返回结构、参数 JSON 化与事务原子化

存储过程作为数据库中执行复杂业务逻辑的重要工具&#xff0c;在提升性能、保障数据一致性和简化维护方面发挥着重要作用。然而&#xff0c;随着应用程序和数据的复杂度不断增加&#xff0c;存储过程也面临着性能瓶颈、维护难度和扩展性问题。为了应对这些挑战&#xff0c;优化…

Lustre Core 语法 - 布尔表达式

Lustre v6 中的 Lustre Core 部分支持的表达式种类中&#xff0c;支持布尔表达式。相关的表达式包括and, or, xor, not, #, nor。 相应的文法定义为 Expression :: not Expression| Expression and Expression| Expression or Expression | Expression xor Expression | # (…

DeepSeek--通向通用人工智能的深度探索者

一、词源与全称 “DeepSeek"由"Deep”&#xff08;深度&#xff09;与"Seek"&#xff08;探索&#xff09;组合而成&#xff0c;中文译名为"深度求索"。其全称为"深度求索人工智能基础技术研究有限公司"&#xff0c;英文对应"De…

模板生成引擎技术介绍

模板生成引擎技术介绍 什么是模板生成引擎&#xff1f; 模板生成引擎是一种用于将数据与预定义的格式相结合&#xff0c;以生成最终文档或网页的技术。它允许开发者通过定义模板和填充数据来自动化内容创建过程。这种技术广泛应用于网站开发、报告生成、电子邮件定制等多个领…

第 5 章:声音与音乐系统

5.1 声音效果的应用 在游戏中&#xff0c;声音效果是增强游戏沉浸感和趣味性的重要元素。Pygame 提供了强大的音频处理功能&#xff0c;使得添加各种声音效果变得相对简单。声音效果可以包括角色的动作音效&#xff0c;如跳跃、攻击、受伤时的声音&#xff1b;环境音效&#x…

matlab中,fill命令用法

在 MATLAB 中&#xff0c;fill 命令用于创建填充多边形的图形对象。使用 fill 可以在二维坐标系中绘制填充的区域&#xff0c;通常用于绘制图形的背景或显示数据分布。 基本语法 fill(X, Y, C)X 和 Y 是同样长度的向量&#xff0c;定义了多边形的顶点坐标。C 是颜色&#xff0…

ChatGPT 搜索测试整合记忆功能

据 TestingCatalog 报道&#xff0c;OpenAI 正在测试 ChatGPT 搜索的整合记忆功能&#xff0c;被命名为 “Memory in search”2。以下是关于该功能的具体情况123&#xff1a; 功能特点 个性化搜索&#xff1a;启用该功能后&#xff0c;ChatGPT 能利用存储的记忆数据&#xff0…

新站如何快速获得搜索引擎收录?

本文来自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/8.html 新站想要快速获得搜索引擎收录&#xff0c;需要采取一系列有针对性的策略。以下是一些具体的建议&#xff1a; 一、网站内容优化 高质量原创内容&#xff1a; 确保网站内容原创、…

指定dpkg安装deb包时的安装路径

通过install和ctonrol文件设置安装路径 在使用dpkg安装.deb包时&#xff0c;一般不能直接指定安装路径&#xff0c;因为.deb包内部已经定义了文件的安装位置。这些位置是在打包.deb包时通过控制文件&#xff08;通常是debian/control和debian/install等文件&#xff09;指定的…

开发者交流平台项目部署到阿里云服务器教程

本文使用PuTTY软件在本地Windows系统远程控制Linux服务器&#xff1b;其中&#xff0c;Windows系统为Windows 10专业版&#xff0c;Linux系统为CentOS 7.6 64位。 1.工具软件的准备 maven&#xff1a;https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-m…

汽车定速巡航

配备定速巡航功能的车型&#xff0c;一般在方向盘附近设有4~6个按键&#xff08;可能共用键位&#xff09;。 要设置定速巡航&#xff0c;不仅需要方向盘上的按键&#xff0c;还要油门配合。 设置的一般流程&#xff1a; 开关&#xff1a;类似步枪上的“保险”&#xff0c;按…

C++11中array容器的常见用法

文章目录 一、概述二、std::array的特点三、std::array的定义与初始化三、std::array的常用成员函数四、与 C 风格数组的互操作 一、概述 在 C11 中&#xff0c;std::array 是一个新的容器类型&#xff0c;它提供了一个固定大小的数组封装。相比传统的 C 风格数组&#xff0c;…

Vue 响应式渲染 - 待办事项简单实现

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue 响应式渲染 - 待办事项简单实现 目录 待办事项简单实现 页面初始化 双向绑定的指令 增加留言列表设置 增加删除按钮 最后优化 总结 待办事项简单实现 页面初始化 对页面进行vue的引入、创建输入框和按钮及实例化V…

中文输入法方案

使用了三年的自然码双拼&#xff0c;毫无疑问是推荐使用双拼输入法。 三年积累下来的习惯是&#xff1a; 1 自然码方案 2 空格出字 字母选字 直到如今&#xff0c;想要做出改变&#xff0c;是因为这样的方案带来的痛点&#xff1a; 1 使用空格出字就无法使用辅助码&#…

scrol家族 offset家族 client家族学习

Scroll 系列属性 scrollTop & scrollLeft scrollTop: 返回元素的内容已向上滚动的部分的高度。scrollLeft: 返回元素的内容已向左滚动的部分的宽度。 scrollHeight & scrollWidth scrollHeight: 返回元素的实际高度&#xff0c;包括由于溢出而在屏幕上不可见的内容…

Python 函数魔法书:基础、范例、避坑、测验与项目实战

Python 函数魔法书&#xff1a;基础、范例、避坑、测验与项目实战 内容简介 本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南&#xff0c;旨在帮助读者从基础入门到项目实战&#xff0c;全面提升编程能力。文章结构由 5 个版块组成&#xff0c;内容层层递进…