通过AI自动生成springboot的CRUD以及单元测试与压力测试源码(二)

embedded/2025/3/18 9:03:21/

本篇文章分为三个部分,即:
通过AI自动生成springboot的CRUD以及单元测试压力测试源码(一)
通过AI自动生成springboot的CRUD以及单元测试压力测试源码(二)
通过AI自动生成springboot的CRUD以及单元测试压力测试源码(完整版)


文章目录

  • 四、生成UserController的单元测试
  • 五、生成UserController压力测试
  • 六、验证
  • 七、Aicoder其他的功能
    • 1、针对某个方法生成单元测试
    • 2、针对代码生成注释
    • 3、代码解释
    • 4、缺陷检测


四、生成UserController的单元测试

aicoder的对话框内输入“生成UserController的单元测试类”指令,其就可以自动的生成了代码,示例如下:
在这里插入图片描述
生成的源码如下。

  • 添加测试依赖
    确保你的 pom.xml 文件包含以下测试依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
package com.win.test;import com.win.bean.User;
import com.win.control.UserController;
import com.win.service.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;import java.util.Arrays;
import java.util.Optional;@Nested
@WebMvcTest(UserController.class)
class UserControllerTest {@Autowiredprivate MockMvc mockMvc;@MockBeanprivate UserService userService;private User user1;private User user2;/*** 在每个测试方法执行之前运行的设置方法。* 用于初始化测试所需的用户对象。*/@BeforeEachpublic void setUp() {// 创建用户1,ID为1,姓名为"alan",年龄为18,邮箱为"alan.chan.chn@163.com"user1 = new User(1L, "alan", 18, "alan.chan.chn@163.com");// 创建用户2,ID为2,姓名为"alanchan",年龄为18,邮箱为"alan.chan.chn@163.com"user2 = new User(2L, "alanchan", 18, "alan.chan.chn@163.com");}/*** 测试获取所有用户的方法。*/@Testpublic void testGetAllUsers() throws Exception {// 模拟 userService 的行为Mockito.when(userService.getAllUsers()).thenReturn(Arrays.asList(user1, user2));// 发送 GET 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.get("/users").accept(MediaType.APPLICATION_JSON))// 验证响应状态码为 200 OK.andExpect(MockMvcResultMatchers.status().isOk())// 验证响应内容为 JSON 格式,包含两个用户对象.andExpect(MockMvcResultMatchers.content().json("[{\"id\":1,\"name\":\"alan\",\"age\":18,\"email\":\"alan.chan.chn@163.com\"},{\"id\":2,\"name\":\"alanchan\",\"age\":18,\"email\":\"alan.chan.chn@163.com\"}]"));}/*** 测试 getUserById 方法的单元测试。* 该测试方法使用 Mockito 模拟 userService 的行为,并使用 MockMvc 发送 GET 请求以验证响应。* 测试包括两个场景:存在用户和不存在用户。*/@Testpublic void testGetUserById() throws Exception {// 模拟 userService 的行为Mockito.when(userService.getUserById(1L)).thenReturn(Optional.of(user1));// 发送 GET 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.get("/users/1").accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().json("{" +"\"id\":1," +"\"name\":\"alan\"," +"\"age\":18," +"\"email\":\"alan.chan.chn@163.com\"}"));// 测试不存在的用户Mockito.when(userService.getUserById(999L)).thenReturn(Optional.empty());// 发送 GET 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.get("/users/999").accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isNotFound());}/*** 测试创建用户的方法。* 该测试方法使用Mockito模拟userService的行为,并使用MockMvc发送POST请求,验证响应状态和内容。*/@Testpublic void testCreateUser() throws Exception {// 创建一个用户对象,不包含idUser user = new User(null, "alanchanchn", 20, "alan.chan.chn@163.com");// 模拟 userService 的行为// 当调用 userService.createUser(user) 时,返回一个id为3的用户对象User createdUser = new User(3L, "alanchanchn", 20, "alan.chan.chn@163.com");Mockito.when(userService.createUser(user)).thenReturn(createdUser);// 发送 POST 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.post("/users").content("{\"name\":\"alanchanchn\",\"age\":20,\"email\":\"alan.chan.chn@163.com\"}").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))// 验证响应状态为200 OK.andExpect(MockMvcResultMatchers.status().isOk())// 验证响应内容是否符合预期的JSON格式.andExpect(MockMvcResultMatchers.content().json("{" +"\"id\":3," +"\"name\":\"alanchanchn\"," +"\"age\":20," +"\"email\":\"alan.chan.chn@163.com\"" +"}"));}/*** 测试 updateUser 方法的单元测试。* 该测试包括两个场景:更新存在的用户和更新不存在的用户。*/@Testpublic void testUpdateUser() throws Exception {// 创建一个用户对象,不包含idUser userToUpdate = new User(null, "alanchanchn", 20, "alan.chan.chn@163.com");// 模拟 userService 的行为// 当调用 userService.updateUser(1L, userToUpdate) 时,返回一个id为1的用户对象User updatedUser = new User(1L, "alanchanchn", 20, "alan.chan.chn@163.com");Mockito.when(userService.updateUser(1L, userToUpdate)).thenReturn(updatedUser);// 发送 PUT 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.put("/users/1").content("{\"name\":\"alanchanchn\",\"age\":20,\"email\":\"alan.chan.chn@163.com\"}").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))// 验证响应状态为200 OK.andExpect(MockMvcResultMatchers.status().isOk())// 验证响应内容是否符合预期的JSON格式.andExpect(MockMvcResultMatchers.content().json("{" +"\"id\":1," +"\"name\":\"alanchanchn\"," +"\"age\":20," +"\"email\":\"alan.chan.chn@163.com\"}"));// 测试不存在的用户Mockito.when(userService.updateUser(999L, userToUpdate)).thenReturn(null);// 发送 PUT 请求并验证响应,期望返回 404 Not FoundmockMvc.perform(MockMvcRequestBuilders.put("/users/999").content("{\"name\":\"alanchanchn\",\"age\":20,\"email\":\"alan.chan.chn@163.com\"}").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isNotFound());}/*** 测试删除用户的功能。* 该测试方法使用Mockito模拟userService的行为,并使用MockMvc发送HTTP DELETE请求。* 测试包括删除存在的用户和删除不存在的用户。*/@Testpublic void testDeleteUser() throws Exception {// 模拟 userService 的行为Mockito.doNothing().when(userService).deleteUser(1L);// 发送 DELETE 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.delete("/users/1").accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isNoContent());// 测试不存在的用户Mockito.doNothing().when(userService).deleteUser(999L);// 发送 DELETE 请求并验证响应mockMvc.perform(MockMvcRequestBuilders.delete("/users/999").accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isNoContent());}
}

五、生成UserController压力测试

aicoder的对话框内输入"生成UserController压力测试类"指令,其就可以自动的生成代码了,示例如下。
在这里插入图片描述
更改了生成源码所在的包。

package com.win.test;import com.fasterxml.jackson.databind.ObjectMapper;
import com.win.bean.User;
import com.win.control.UserController;
import com.win.service.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;@WebMvcTest(UserController.class)
public class UserControllerStressTest {@Autowiredprivate MockMvc mockMvc;@MockBeanprivate UserService userService;private final int threadCount = 1000; // 并发线程数private final int requestCount = 10000; // 总请求数@BeforeEachpublic void setUp() {// 模拟 userService 的行为List<User> users = new ArrayList<>();users.add(new User(1L, "Alice",18, "alice@example.com"));users.add(new User(2L, "Bob",20, "bob@example.com"));when(userService.getAllUsers()).thenReturn(users);when(userService.getUserById(1L)).thenReturn(Optional.ofNullable(users.get(0)));when(userService.getUserById(2L)).thenReturn(Optional.ofNullable(users.get(1)));}@Testpublic void testGetAllUsersStress() throws Exception {AtomicInteger successCount = new AtomicInteger(0);AtomicInteger failureCount = new AtomicInteger(0);CountDownLatch latch = new CountDownLatch(requestCount);ExecutorService executorService = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < requestCount; i++) {executorService.submit(() -> {try {MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/users")).andExpect(status().isOk()).andReturn();successCount.incrementAndGet();} catch (Exception e) {failureCount.incrementAndGet();} finally {latch.countDown();}});}latch.await();executorService.shutdown();System.out.println("成功请求: " + successCount.get());System.out.println("失败请求: " + failureCount.get());}@Testpublic void testGetUserByIdStress() throws Exception {AtomicInteger successCount = new AtomicInteger(0);AtomicInteger failureCount = new AtomicInteger(0);CountDownLatch latch = new CountDownLatch(requestCount);ExecutorService executorService = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < requestCount; i++) {executorService.submit(() -> {try {MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/users/1")).andExpect(status().isOk()).andReturn();successCount.incrementAndGet();} catch (Exception e) {failureCount.incrementAndGet();} finally {latch.countDown();}});}latch.await();executorService.shutdown();System.out.println("成功请求: " + successCount.get());System.out.println("失败请求: " + failureCount.get());}@Testpublic void testCreateUserStress() throws Exception {AtomicInteger successCount = new AtomicInteger(0);AtomicInteger failureCount = new AtomicInteger(0);CountDownLatch latch = new CountDownLatch(requestCount);ExecutorService executorService = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < requestCount; i++) {final int index = i; // 将 i 复制为 final 变量executorService.submit(() -> {try {User user = new User((long) (index + 1000), "User" + index,11, "user" + index + "@example.com");MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/users").contentType("application/json").content(objectMapper.writeValueAsString(user))).andExpect(status().isOk()).andReturn();successCount.incrementAndGet();} catch (Exception e) {failureCount.incrementAndGet();} finally {latch.countDown();}});}latch.await();executorService.shutdown();System.out.println("成功请求: " + successCount.get());System.out.println("失败请求: " + failureCount.get());}@Testpublic void testUpdateUserStress() throws Exception {AtomicInteger successCount = new AtomicInteger(0);AtomicInteger failureCount = new AtomicInteger(0);CountDownLatch latch = new CountDownLatch(requestCount);ExecutorService executorService = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < requestCount; i++) {final int index = i; // 将 i 复制为 final 变量executorService.submit(() -> {try {User user = new User((long) (index + 1000), "User" + index, 12,"user" + index + "@example.com");MvcResult result = mockMvc.perform(MockMvcRequestBuilders.put("/users/1").contentType("application/json").content(objectMapper.writeValueAsString(user))).andExpect(status().isOk()).andReturn();successCount.incrementAndGet();} catch (Exception e) {failureCount.incrementAndGet();} finally {latch.countDown();}});}latch.await();executorService.shutdown();System.out.println("成功请求: " + successCount.get());System.out.println("失败请求: " + failureCount.get());}@Testpublic void testDeleteUserStress() throws Exception {AtomicInteger successCount = new AtomicInteger(0);AtomicInteger failureCount = new AtomicInteger(0);CountDownLatch latch = new CountDownLatch(requestCount);ExecutorService executorService = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < requestCount; i++) {executorService.submit(() -> {try {MvcResult result = mockMvc.perform(MockMvcRequestBuilders.delete("/users/1")).andExpect(status().isOk()).andReturn();successCount.incrementAndGet();} catch (Exception e) {failureCount.incrementAndGet();} finally {latch.countDown();}});}latch.await();executorService.shutdown();System.out.println("成功请求: " + successCount.get());System.out.println("失败请求: " + failureCount.get());}private ObjectMapper objectMapper = new ObjectMapper();
}

六、验证

正常功能验证,比较容易,不再赘述,基本上不会出错。
单元测试的用例可能需要调整一下,因为其没有有参构造函数。
只要单元测试通过,压力测试结果会通过。
示例如下,本示例使用的覆盖率运行,能看到单元测试的覆盖率。
单元测试覆盖率报告可以导出成html文件,可以自己试一试。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
压力测试,运行的时候会自动记录成功与错误的记录数,以及可以观察一下运行机器的网络、cpu、内存以及硬盘的使用情况,当然如果更专业的压力测试则是使用jmeter等专业的软件。

七、Aicoder其他的功能

1、针对某个方法生成单元测试

在这里插入图片描述
点击单元测试,在AiCoder的面板上就生成了该方法对应的单元测试类,示例如下
在这里插入图片描述

2、针对代码生成注释

示例如下
在这里插入图片描述

3、代码解释

点击代码解释,示例如下
在这里插入图片描述

4、缺陷检测

点击缺陷检测,示例如下
在这里插入图片描述

以上通过AICoder插件,我们可以快速生成SpringBoot技术栈的CRUD代码及其单元测试压力测试源码。本示例没有生产前端代码,也可以根据需要进行生成,不再赘述。这不仅大大提高了开发效率,还确保了代码的质量和一致性。希望本文能帮助你更好地利用AICoder插件,提升你的开发体验。

本篇文章分为三个部分,即:
通过AI自动生成springboot的CRUD以及单元测试压力测试源码(一)
通过AI自动生成springboot的CRUD以及单元测试压力测试源码(二)
通过AI自动生成springboot的CRUD以及单元测试压力测试源码(完整版)


http://www.ppmy.cn/embedded/173546.html

相关文章

就像BGP中的AS_PATH一样,无论路途多远,我愿意陪你一起走——基于华为ENSP的BGP的Community[社团属性]深入浅出

本篇技术博文摘要 &#x1f31f; 1. BGP的社团属性&#xff08;Community&#xff09; 定义&#xff1a;BGP中的Community属性用于对路由进行标记和分类&#xff0c;帮助控制路由的传播和策略实施。功能&#xff1a;通过不同的Community标签&#xff0c;可以实现流量的抓取、路…

事件系统简介+Button组件+Toggle简介

UI的事件交互 Canvas添加 Ignore Reversed Graphics:是否忽略Canvas反向的事件操作 Blocking Objects&#xff1a;遮挡事件的物体&#xff08;2D物体【精灵片】&#xff0c;3D物体&#xff09; Blocking Mask:遮挡事件的物体所在的渲染层 交互元素 Raycast Target:是否接收Canv…

HTTP+DNS综合实验

一、实验拓扑 二、实验要求 1、学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到百度网络中的HTTP服务器。 2、学校内部网络基于192.168.1.0/24划分&#xff0c;PC1可以正常访问3.3.3.0/24网段&#xff0c;但是PC2不允许。 3、学校内部网络使用静态路由&#xff0c…

Redis系列:深入理解缓存穿透、缓存击穿、缓存雪崩及其解决方案

在使用Redis作为缓存系统时&#xff0c;我们经常会遇到“缓存穿透”、“缓存击穿”和“缓存雪崩”等问题&#xff0c;这些问题一旦出现&#xff0c;会严重影响应用性能甚至造成服务不可用。因此&#xff0c;理解这些问题的产生原因和解决方案非常重要。 本文将全面讲解缓存穿透…

Kubernetes Network Policy使用场景

0. 运维干货分享 软考高级系统架构设计师备考学习资料软考高级网络规划设计师备考学习资料Kubernetes CKA认证学习资料分享信息安全管理体系&#xff08;ISMS&#xff09;制度模板分享免费文档翻译工具(支持word、pdf、ppt、excel)PuTTY中文版安装包MobaXterm中文版安装包ping…

基本不等式

基本不等式&#xff1a; 三种形式&#xff1a; 和积式 x -2xy y 0 (x>0, y>0) x y 2xy x y √2xy 非齐此式 其次式 如下图所示&#xff1a; 不等式的三种解法&#xff1a; 换元法&#xff1a;&#xff08;乘积复杂就换乘积&#xff0c;分母复杂就换分母&#xff…

推理大模型的后训练增强技术-Reasoning模型也进化到2.0了,这次居然学会用工具了

论文题目&#xff1a;START: Self-taught Reasoner with Tools 论文链接&#xff1a;https://arxiv.org/pdf/2503.04625 论文简介 Reasoning模型也进化到2.0了&#xff0c;这次居然学会用工具了&#xff01;✨ 最近有个叫START的方法&#xff0c;让大模型也能学着用工具&#…

消息队列导致数据库数据读取不一致解决方案

我使用的是在数据库添加一个版本字段&#xff0c;记录版本&#xff0c;保证版本一致性&#xff0c;就能保证每次读取的是需要的内容。 具体问题&#xff1a;使用消息队列时&#xff0c;发送方给接收方发送消息&#xff0c;接收方修改了数据库的同时发送方查询数据库&#xff0…