SpringBoo项目标准测试样例

文章目录

    • 概要
    • Controller Api 测试
      • 源码
      • 单元测试
      • 集成测试

概要

Spring Boot项目测试用例

测试方式是否调用数据库使用的注解特点
单元测试(Mock Service)❌ 不调用数据库@WebMvcTest + @MockBean只测试 Controller 逻辑,速度快
集成测试(真实数据库)✅ 调用数据库@SpringBootTest真实保存数据,确保数据库逻辑正确

Controller Api 测试

Restful Api

源码

package cn.star.framework.example.controller;

import cn.star.framework.controller.AbstractController;
import cn.star.framework.core.api.AppResult;
import cn.star.framework.core.api.Pageable;
import cn.star.framework.example.entity.Example;
import cn.star.framework.example.service.ExampleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * ExampleController<br>
 *
 * @author zhaoweiping
 *     <p style='color: red'>Created on 2025-02-06 16:16:40
 * @since 3.0.0
 */
@RestController
@RequestMapping(value = "/example")
@Api(tags = "框架测试")
public class ExampleController extends AbstractController<Example, String> {
  @Autowired @Getter private ExampleService service;

  @Override
  @PostMapping
  @ApiOperation(value = "新增")
  public AppResult<Example> save(@RequestBody Example entity) {
    return super.save(entity);
  }

  @Override
  @PutMapping
  @ApiOperation(value = "更新")
  public AppResult<Example> update(@RequestBody Example entity) {
    return super.update(entity);
  }

  @Override
  @DeleteMapping
  @ApiOperation(value = "删除")
  public AppResult<List<Example>> deleteByIds(@RequestBody String... ids) {
    return super.deleteByIds(ids);
  }

  @GetMapping
  @ApiOperation(value = "查询(列表)")
  public AppResult<List<Example>> list(HttpServletRequest request) {
    return super.list(request, Example.class);
  }

  @Override
  @GetMapping("/{id}")
  @ApiOperation(value = "查询(主键)")
  public AppResult<Example> get(@PathVariable(value = "id") String id) {
    return super.get(id);
  }

  @GetMapping("/page")
  @ApiOperation(value = "查询(分页)")
  public AppResult<Pageable<Example>> pageable(HttpServletRequest request) {
    return super.pageable(request, Example.class);
  }
}

单元测试

package cn.star.framework.example.controller;

import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import cn.hutool.json.JSONUtil;
import cn.star.framework.example.entity.Example;
import cn.star.framework.example.service.ExampleService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
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.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

/**
 * 单元测试<br>
 *
 * @author zhaoweiping
 *     <p style='color: red'>Created on 2025-02-06 18:52:28
 * @since 3.0.0
 */
@Slf4j
@RunWith(SpringRunner.class)
@WebMvcTest(ExampleController.class)
public class ExampleControllerMockTest {
  @Autowired private MockMvc mockMvc;
  @MockBean private ExampleService exampleService;

  @Before
  public void setup() {
    log.info("setup ...");
  }

  @Test
  public void save() throws Exception {
    Example example = new Example("1", "新增");

    // 不会调用真实数据库操作
    when(exampleService.save(Mockito.any(Example.class))).thenReturn(example);

    mockMvc
        .perform(
            post("/example")
                .contentType(MediaType.APPLICATION_JSON)
                .content(JSONUtil.toJsonStr(example)))
        // 断言
        .andExpect(status().isOk())
        // 打印结果
        .andDo(System.out::println)
        .andDo(result -> System.out.println(result.getResponse().getContentAsString()));
  }
}

集成测试

package cn.star.framework.example.controller;

import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;

import cn.hutool.json.JSONUtil;
import cn.star.framework.core.Constant;
import cn.star.framework.example.entity.Example;
import cn.star.framework.example.service.ExampleService;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

/**
 * 集成测试<br>
 *
 * @author zhaoweiping
 *     <p style='color: red'>Created on 2025-02-06 18:52:28
 * @since 3.0.0
 */
@Slf4j
@RunWith(SpringRunner.class)
@EntityScan(basePackages = Constant.BASE_PACKAGE)
@EnableJpaRepositories(basePackages = Constant.BASE_PACKAGE)
@ComponentScan(basePackages = Constant.BASE_PACKAGE)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ExampleControllerTest {
  @Autowired private WebApplicationContext context;
  @Autowired private ExampleService exampleService;

  /** 在集成测试中不会自动创建,需要手动初始化 */
  @Autowired(required = false)
  private MockMvc mockMvc;

  @Before
  public void setup() {
    log.info("setup ...");
    mockMvc = webAppContextSetup(context).build();
  }

  @Test
  public void save() throws Exception {
    Example example = new Example("1", "新增");

    // 不会调用真实数据库操作
    System.out.println(exampleService);

    mockMvc
        .perform(
            post("/example")
                .contentType(MediaType.APPLICATION_JSON)
                .content(JSONUtil.toJsonStr(example)))
        // 断言
        .andExpect(status().isOk())
        // 打印结果
        .andDo(System.out::println)
        .andDo(result -> System.out.println(result.getResponse().getContentAsString()));

    List<Example> examples = exampleService.findAll();
    System.out.println(examples);
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【STM32系列】利用MATLAB配合ARM-DSP库设计IIR数字滤波器(保姆级教程)

ps.源码放在最后面 设计FIR数字滤波器可以看这里&#xff1a;利用MATLAB配合ARM-DSP库设计FIR数字滤波器&#xff08;保姆级教程&#xff09; 设计IIR滤波器 MATLAB配置 设计步骤 首先在命令行窗口输入"filterDesigner"&#xff0c;接着就会跳出以下界面&#xf…

WSL2中安装的ubuntu搭建tftp服务器uboot通过tftp下载

Windows中安装wsl2&#xff0c;wsl2里安装ubuntu。 1. Wsl启动后 1&#xff09;Windows下ip ipconfig 以太网适配器 vEthernet (WSL (Hyper-V firewall)): 连接特定的 DNS 后缀 . . . . . . . : IPv4 地址 . . . . . . . . . . . . : 172.19.32.1 子网掩码 . . . . . . . .…

ES冷热数据分离配置

冷热数据是根据索引创建时间来进行迁移的。一旦迁移到冷数据节点&#xff0c;则无法再恢复成热数据&#xff0c;因为热数据节点中该索引已经没有分片存在了。 基于Docker搭建ES集群,并设置冷热数据节点 配置冷热数据迁移策略 PUT https://192.168.x.xx:19200/_ilm/policy/my…

Javaweb学习日记(十一)Mybatis-基础操作

一、环境准备 二、基础操作-删除 日志输出&#xff1a; SQL注入&#xff1a; sql注入&#xff1a;例如一个登录页面&#xff0c;需要满足账号密码同时匹配数据库内的数据才可登录&#xff08;点击登录也页面在后台生成一条sql语句去检验是否正确&#xff08;通过判断sql语句返…

小程序-基础加强

前言 这一节把基础加强讲完 1. 导入需要用到的小程序项目 2. 初步安装和使用vant组件库 这里还可以扫描二维码 其中步骤四没什么用 右键选择最后一个 在开始之前&#xff0c;我们的项目根目录得有package.json 没有的话&#xff0c;我们就初始化一个 但是我们没有npm这个…

Spring @PropertySource:让你的应用配置更加模块化和可维护

PropertySource注解在Spring中的作用&#xff0c;就像是给Spring应用配了一个“外部配置箱”。 想象一下&#xff0c;你在开发一个Spring应用时&#xff0c;有很多配置信息需要设置&#xff0c;比如数据库的连接信息、应用的某些功能开关等。如果这些信息都硬编码在代码中&…

尝试在Excel里调用硅基流动上的免费大语言模型

我个人觉得通过api而不是直接浏览器客户端聊天调用大语言模型是使用人工智能大模型的一个相对进阶的阶段。 于是就尝试了一下。我用的是老师木 袁进辉博士新创的硅基流动云上的免费的大模型。——虽然自己获赠了不少免费token&#xff0c;但测试阶段用不上。 具体步骤如下&am…

问卷数据分析|SPSS之分类变量描述性统计

1.点击分析--描述统计--频率 2. 选中分类变量&#xff0c;点击中间箭头 3.图表选中条形图&#xff0c;图表值选择百分比&#xff0c;选择确定 4.这里显示出了描述性统计的结果 5.下面就是图形&#xff0c;但SPSS画的图形都不是很好啊看&#xff0c;建议用其他软件画图&#xff…

生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (上)

今天小李哥将开启全新的技术分享系列&#xff0c;为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来&#xff0c;生成式 AI 安全市场正迅速发展。据 IDC 预测&#xff0c;到 2025 年全球 AI 安全解决方案市场规模将突破 200 亿美元&#xff0c;年复合增长率超过 30%…

LQB(0)-python-基础知识

一、Python开发环境与基础知识 python解释器&#xff1a;用于解释python代码 方式&#xff1a; 1.直接安装python解释器 2.安装Anaconda管理python环境 python开发环境&#xff1a;用于编写python代码 1.vscode 2.pycharm # 3.安装Anaconda后可以使用网页版的jupyter n…

SQL Server 数据库备份指南

SQL Server备份是数据库维护的日常工作。备份的目的是在发生数据丢失、损坏甚至硬件故障时将数据库和事务日志恢复到最近的时间点。您可以借助专业的SQL Server备份软件,操作起来更方便。前提需要安装SQL Server Management Studio (SSMS)工具。 对于 SQL 数据库备份,有多种…

常见Linux命令的复习

常见命令 ls 列出工作目录 ls -l&#xff1a;以长格式显示目录下的文件和子目录信息。ls -a&#xff1a;显示所有文件和子目录&#xff0c;包括隐藏文件 ll 列出该目录下的详细信息 看到该目录下的所有目录和文件的详细信息 cd 切换当前工作目录里 cd /path/to/directory&…

spring aop失效场景

aop基于代理&#xff08;jdk动态代理 / cglib代理&#xff09;实现&#xff0c;即new了新的类实例&#xff0c;代理了原来的定义的类实例。 目录 1. final修饰的方法无法被代理2. 静态方法无法被代理3. 内部方法调用&#xff0c;即this.method()无法被代理4. 私有方法不能代理5…

PostgreSQL函数自动Commit/Rollback所带来的问题

一、综述 今天在PostgreSQL遇到一个奇怪的现象&#xff0c;简而言之&#xff0c;是想用函数&#xff08;存储过程&#xff09;实现插入记录&#xff0c;整个过程没报错但事后却没找到记录&#xff01;忙活半天&#xff0c;才发现原因是PostgreSQL函数&#xff08;存储过程&…

Ollama+deepseek+Docker+Open WebUI实现与AI聊天

1、下载并安装Ollama 官方网址&#xff1a;Ollama 安装好后&#xff0c;在命令行输入&#xff0c; ollama --version 返回以下信息&#xff0c;则表明安装成功&#xff0c; 2、 下载AI大模型 这里以deepseek-r1:1.5b模型为例&#xff0c; 在命令行中&#xff0c;执行&…

Immutable设计 SimpleDateFormat DateTimeFormatter

专栏系列文章地址&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标&#xff1a; 理解不可变设计模式&#xff0c;时间format有线程安全要求的注意使用DateTimeFormatter 目录 ImmutableSimpleDateFormat 非线程安全可以synchronized解决&a…

基于Hexo实现一个静态的博客网站

原文首发&#xff1a;https://blog.liuzijian.com/post/8iu7g5e3r6y.html 目录 引言1.初始化Hexo2.整合主题Fluid3.部署评论系统Waline4.采用Nginx部署 引言 Hexo是中国台湾开发者Charlie在2012年创建的一个开源项目&#xff0c;旨在提供一个简单、快速且易于扩展的静态博客生…

Diskgenius系统迁移之后无法使用USB启动

前言 本文用于记录系统迁移中遇到的问题及解决方法&#xff0c;如有不对请指出&#xff0c;谢谢&#xff01; 现象 使用DiskGenius进行系统迁移后&#xff0c;使用USB启动失败&#xff0c;反复在品牌logo和黑屏之间切换&#xff0c;期间还会在左上角显示”reset system“报错…

数据库系统概论的第六版与第五版的区别,附pdf

我用夸克网盘分享了「数据库系统概论第五六版资源」&#xff0c;点击链接即可保存。 链接&#xff1a;https://pan.quark.cn/s/21a278378dee 第6版教材修订的主要内容 为了保持科学性、先进性和实用性&#xff0c;在第5版教材基础上对全书内容进行了修改、更新和充实。 在科…

简单说一下CAP理论和Base理论

CAP理论 什么是CAP 一致性 可用性 分区容错性&#xff1a;系统如果不能再时限内达成数据一致性&#xff0c;就说明发生了分区的情况 然后当前操作在C和A之间做出选择 例如我的网络出现问题了&#xff0c;但是我们的系统不能因为网络问题就直接崩溃 只要我们的分布式系统没…