Spring Boot 进行 MockMvc 单元测试的实例

在Spring Boot应用程序中,使用MockMvc进行单元测试是一种有效的方式,可以验证控制器的行为和API的正确性。在这篇博客中,我们将介绍如何使用MockMvc对用户控制器(UserController)进行测试,该控制器涉及用户信息的增删改查操作。

UserController测试类

package com.lfsun.mockmvc;import com.fasterxml.jackson.databind.ObjectMapper;
import com.lfsun.mockmvc.entity.User;
import com.lfsun.mockmvc.service.UserService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;import java.util.Arrays;
import java.util.List;import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {@Autowiredprivate MockMvc mockMvc;@Autowiredprivate UserService userService;@Autowiredprivate ObjectMapper objectMapper;@Beforepublic void setUp() {// 在测试前初始化一些数据,或者使用Mockito进行一些mock设置}@Testpublic void getAllUsersTest() throws Exception {mockMvc.perform(MockMvcRequestBuilders.get("/user/getAllUsers")).andExpect(status().isOk()).andExpect(jsonPath("$").isArray()).andExpect(jsonPath("$.length()").value(userService.getAllUsers().size())).andDo(print());}@Testpublic void getUserByIdTest() throws Exception {Long userId = 1L;mockMvc.perform(MockMvcRequestBuilders.get("/user/getUserById/{userId}", userId)).andExpect(status().isOk()).andExpect(jsonPath("$.userId").value(userId)).andDo(print());}@Testpublic void addUserTest() throws Exception {User user = new User();user.setUsername("testUser");user.setEmail("test@lfsun.com");mockMvc.perform(MockMvcRequestBuilders.post("/user/addUser").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(user))).andExpect(status().isOk()).andExpect(jsonPath("$.username").value("testUser")).andExpect(jsonPath("$.email").value("test@lfsun.com")).andDo(print());}@Testpublic void updateUserTest() throws Exception {Long userId = 1L;User updatedUser = new User();updatedUser.setUserId(userId);updatedUser.setUsername("updatedUser");updatedUser.setEmail("updated@lfsun.com");mockMvc.perform(MockMvcRequestBuilders.put("/user/updateUser").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(updatedUser))).andExpect(status().isOk()).andExpect(jsonPath("$.userId").value(userId)).andExpect(jsonPath("$.username").value("updatedUser")).andExpect(jsonPath("$.email").value("updated@lfsun.com")).andDo(print());}@Testpublic void deleteUserTest() throws Exception {Long userId = 1L;mockMvc.perform(MockMvcRequestBuilders.delete("/user/deleteUser/{userId}", userId)).andExpect(status().isOk()).andDo(print());}
}

解释和注意事项

  1. MockMvc的注入: @Autowired 注解用于将MockMvc实例注入测试类中。
  2. 数据初始化: 使用 @Before 注解的 setUp 方法,可以在测试前进行一些数据初始化或使用Mockito进行一些mock设置。
  3. 测试方法: 每个测试方法使用MockMvc执行相应的HTTP请求,并使用断言验证控制器的响应是否符合预期。
  4. 数据序列化: ObjectMapper 负责将对象序列化为JSON,以便在POST和PUT请求中传递。

以下附上完整代码

controller:

package com.lfsun.mockmvc.controller;import com.lfsun.mockmvc.entity.User;
import com.lfsun.mockmvc.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** 用户 Controller** @author CL*/
@RestController
@RequestMapping(value = "/user")
@RequiredArgsConstructor
public class UserController {private final UserService userService;// 查询所有用户@GetMapping("/getAllUsers")public List<User> getAllUsers() {return userService.getAllUsers();}// 根据用户ID查询用户@GetMapping("/getUserById/{userId}")public User getUserById(@PathVariable Long userId) {return userService.getUserById(userId);}// 添加用户@PostMapping("/addUser")public User addUser(@RequestBody User user) {return userService.addUser(user);}// 更新用户信息@PutMapping("/updateUser")public User updateUser(@RequestBody User user) {return userService.updateUser(user);}// 根据用户ID删除用户@DeleteMapping("/deleteUser/{userId}")public void deleteUser(@PathVariable Long userId) {userService.deleteUser(userId);}
}

service、serviceimpl

package com.lfsun.mockmvc.service;import com.lfsun.mockmvc.entity.User;import java.util.List;/*** 用户 Service 接口*/
public interface UserService {// 查询所有用户List<User> getAllUsers();// 根据用户ID查询用户User getUserById(Long userId);// 添加用户User addUser(User user);// 更新用户信息User updateUser(User user);// 根据用户ID删除用户void deleteUser(Long userId);
}
package com.lfsun.mockmvc.service.impl;import com.lfsun.mockmvc.entity.User;
import com.lfsun.mockmvc.mapper.UserMapper;
import com.lfsun.mockmvc.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** 用户 Service 实现类*/
@Service
@AllArgsConstructor  // Lombok 自动生成构造函数
public class UserServiceImpl implements UserService {private final UserMapper userMapper;@Overridepublic List<User> getAllUsers() {return userMapper.getAllUsers();}@Overridepublic User getUserById(Long userId) {return userMapper.getUserById(userId);}@Overridepublic User addUser(User user) {userMapper.addUser(user);return user;}@Overridepublic User updateUser(User user) {userMapper.updateUser(user);return user;}@Overridepublic void deleteUser(Long userId) {userMapper.deleteUser(userId);}
}

mapper

package com.lfsun.mockmvc.mapper;import com.lfsun.mockmvc.entity.User;
import org.apache.ibatis.annotations.*;import java.util.List;/*** 用户 Mapper 接口*/
@Mapper
public interface UserMapper {List<User> getAllUsers();User getUserById(Long userId);void addUser(User user);void updateUser(User user);void deleteUser(Long userId);
}

实体类:

package com.lfsun.mockmvc.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Long userId;private String username;private String email;}

xml

<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.lfsun.mockmvc.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.lfsun.mockmvc.entity.User"><id column="user_id" property="userId" jdbcType="BIGINT"/><result column="username" property="username" jdbcType="VARCHAR"/><result column="email" property="email" jdbcType="VARCHAR"/></resultMap><!-- 查询所有用户 --><select id="getAllUsers" resultMap="BaseResultMap">SELECT *FROM user;</select><!-- 根据用户ID查询用户 --><select id="getUserById" resultMap="BaseResultMap" parameterType="java.lang.Long">SELECT *FROM userWHERE user_id = #{userId};</select><!-- 添加用户 --><insert id="addUser" parameterType="com.lfsun.mockmvc.entity.User">INSERT INTO user (username, email)VALUES (#{username}, #{email});</insert><!-- 更新用户信息 --><update id="updateUser" parameterType="com.lfsun.mockmvc.entity.User">UPDATE userSET username = #{username},email    = #{email}WHERE user_id = #{userId};</update><!-- 根据用户ID删除用户 --><delete id="deleteUser" parameterType="java.lang.Long">DELETEFROM userWHERE user_id = #{userId};</delete></mapper>

配置

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/mockmvc?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=trueusername: rootpassword: 123321mybatis:mapper-locations: classpath:/mapper/*.xml  # 指定 MyBatis mapper 文件的位置configuration:map-underscore-to-camel-case: true  # 配置驼峰命名规则

maven

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.14</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lfsun</groupId><artifactId>lfsun-study-mockmvc</artifactId><version>0.0.1-SNAPSHOT</version><name>lfsun-study-mockmvc</name><description>lfsun-study-mockmvc</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version><scope>compile</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

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

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

相关文章

数据库单表查询

1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工和最低工资。 5、列出职工的平均工资和总工资。 6、创建一个只有职工号、姓名和参加工作的新表&#xff0c;名为工作日期表…

线上问题整理

JVM 案例 案例一&#xff1a;服务器内存不足&#xff0c;影响Java应用 问题&#xff1a; 收到报警&#xff0c;某Java应用集群中一台服务器可用内存不足&#xff0c;超过报警阈值。 排查过程&#xff1a; 首先&#xff0c;通过Hickwall查看该应用各项指标&#xff0c;发现无论…

224.【2023年华为OD机试真题(C卷)】英文输入法(JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-英文输入法二.解题思路三.题解代码Python题解代…

Linux第22步_安装CH340驱动和串口终端软件MobaXterm

开发板输出信息通常是采用串口&#xff0c;而计算机通常是USB接口&#xff0c;为了让他们之间能够交换数据&#xff0c;我们通常采用USB转串口的转换器来实现。目前市场上的串口转换器大多是采用CH340芯片来实现的&#xff0c;因此我们需要在计算中安装一个CH340驱动程序&#…

[代码复现]BrainGNN: Interpretable Brain Graph Neural Network for fMRI Analysis

目录 1. 论文资料 2. 代码复现步骤及可能存在的问题 2.1. 环境配置 2.2. 代码运行 3. 为啥跑这个代码 1. 论文资料 &#xff08;1&#xff09;论文原文&#xff1a;BrainGNN&#xff1a;用于fMRI分析的可解释脑图神经网络 - ScienceDirect &#xff08;2&#xff09;论文…

Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

前言 在项目研发中&#xff0c;相信大家都遇到过给用户增加头像照片的需求。 随着手机版本的不断更新&#xff0c;android 8、android 9、android 10、android 12、android 13、鸿蒙系统等等&#xff1b;遇到这个功能需求&#xff0c;大家肯定会想&#xff0c;“这还不好写&…

【Python学习】Python学习17- File(文件) 方法

目录 [TOC](【Python学习】Python学习17- File(文件) 方法) 文章所属专区 Python学习 前言 本章节主要说明Python文件操作的具体说明 open()方法 Python open() 方法用于打开一个文件&#xff0c;并返回文件对象&#xff0c;在对文件进行处理过程都需要使用到这个函数&#…

Spark算子(RDD)超细致讲解

SPARK算子&#xff08;RDD&#xff09;超细致讲解 map,flatmap,sortBykey, reduceBykey,groupBykey,Mapvalues,filter,distinct,sortBy,groupBy共10个转换算子 &#xff08;一&#xff09;转换算子 1、map from pyspark import SparkContext# 创建SparkContext对象 sc Spark…

信息系统中的需求分析

软件需求是指用户对新系统在功能、行为、性能、设计约束等方面的期望。根据IEEE的软件工程标准词汇表&#xff0c;软件需求是指用户解决问题或达到目标所需的条件或能力&#xff0c;是系统或系统部件要满足合同、标准、规范或其他正式规定文档所需具有的条件或能力&#xff0c;…

Fastjson库将JSONObject转换为实体类

嗨&#xff0c;大家好&#xff0c;欢迎来到程序猿漠然公众号&#xff0c;我是漠然。 在Java编程中&#xff0c;使用Fastjson库将JSONObject转换为实体类的过程是一种常见的数据处理操作。Fastjson是一个由阿里巴巴开发的高性能JSON处理库&#xff0c;它简化了JSON数据的读写操作…

传感数据分析——傅里叶滤波:理论与公式

传感数据分析——傅里叶滤波&#xff1a;理论与公式 引言 在传感数据分析领域&#xff0c;傅里叶滤波是一种重要的信号处理技术&#xff0c;被广泛应用于各种领域&#xff0c;如通信、图像处理、音频处理以及生物医学等。本文将简单探讨傅里叶滤波的理论基础和相关公式&#…

Azure Machine Learning - 视频AI技术

Azure AI 视频索引器是构建在 Azure 媒体服务和 Azure AI 服务&#xff08;如人脸检测、翻译器、Azure AI 视觉和语音&#xff09;基础之上的一个云应用程序&#xff0c;是 Azure AI 服务的一部分。 有了 Azure 视频索引器&#xff0c;就可以使用 Azure AI 视频索引器视频和音频…

向伟人学习反焦虑,在逆境中崛起

第一、乐观的精神。 伟人在长期以来的读书、思考和实践&#xff0c;突破了思想认知限制&#xff0c;并最终在更高的思维层面上&#xff0c;建立起了强大的精神信念感。 在危险环境中表示绝望的人&#xff0c; 在黑暗中看不见光明的人&#xff0c; 只是懦夫与机会主义者。 —— …

蓝桥杯练习题(八)

&#x1f4d1;前言 本文主要是【算法】——蓝桥杯练习题&#xff08;八&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 …

[晓理紫]每日论文推送(有中文摘要,源码或项目地址)--机器人、视觉相关

专属领域论文订阅 VX关注{晓理紫}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 二维码 分类: 大语言模型LLM视觉模型VLM扩散模型视觉导航具身智能&#xff0c;机器人强化学习开放词汇&#xff0c;检测分割 晓理紫今日论…

二叉树的中序遍历【二叉树】【递归】

Problem: 94. 二叉树的中序遍历 文章目录 思路 & 解题方法复杂度Code 思路 & 解题方法 二叉树简单递归。 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) Code # Definition for a binary tree node. # class TreeNode: # def __init__(se…

Java重修第五天—面向对象3

通过学习本篇文章可以掌握如下知识 1、多态&#xff1b; 2、抽象类&#xff1b; 3、接口。 之前已经学过了继承&#xff0c;static等基础知识&#xff0c;这篇文章我们就开始深入了解面向对象多态、抽象类和接口的学习。 多态 多态是在继承/实现情况下的一种现象&#xf…

【汇编要笑着学】汇编模块化编程 | call和ret调用指令 | jmp跳转指令 | inc自加指令

Ⅰ.汇编模块化编程 0x00 一个简单的例子 我们了解模块化编程前先给出一个例子&#xff0c;方便大家快速了解。 SECTION MBR vstart0x7c00 ; 起始地址编译在0x7c00mov ax,cs mov ds,ax mov es,axmov ss,axmov fs,axmov sp,0x7c00 ; 上面这些都没什…

【工作日语】二、IT用语

バグ 缺陷ボタン 按钮チックする 检查クリアする 清除クリックする 点击クライアント 客户机コーディング 编码コマンド 命令コメント 注释コンパイルする 编译コンピュータ 计算机コントロール 控制カーソル 光标データ 数据データベース 数据库デバッグ 调试ドキュメント 文…

camtasia studio2024免费版如何下载?怎么录屏?

camtasia studio怎么录屏&#xff1f;Camtasia Studio是一款专门录制屏幕动作的工具&#xff0c;它能在任何颜色模式下轻松地记录屏幕动作&#xff0c;包括影像、音效、鼠标移动轨迹、解说声音等等。一般情况下&#xff0c;用户使用camtasia studio进行录屏时&#xff0c;需要注…