Java Web开发高级——单元测试与集成测试

测试是软件开发的重要环节,确保代码质量和功能的正确性。在Spring Boot项目中,单元测试和集成测试是常用的两种测试类型:

  • 单元测试:测试单个模块(如类或方法)是否按预期工作。
  • 集成测试:测试多个模块的交互是否正确。

本节内容将深入探讨如何在Spring Boot应用中使用现代工具和框架(如JUnit、Mockito、MockMvc)进行单元测试和集成测试。


1. JUnit与Mockito基础
1.1 JUnit简介

JUnit是Java生态中最常用的测试框架,它提供了简洁、强大的API来编写、组织和执行测试用例。
特点

  • 支持注解(如@Test@BeforeEach)。
  • 集成良好,兼容Maven、Gradle等构建工具。
  • 与IDE的测试视图无缝结合。
1.2 JUnit 5关键特性

JUnit 5(又称为JUnit Jupiter)是JUnit的最新版本,与JUnit 4相比,新增了以下特性:

  • @BeforeEach@AfterEach:取代JUnit 4中的@Before@After,在每个测试用例前后运行。
  • @ParameterizedTest:支持参数化测试。
  • Assertions:提供丰富的断言方法,如assertEqualsassertThrows

示例代码:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;class CalculatorTest {@Testvoid testAddition() {int result = 2 + 3;assertEquals(5, result);}
}
1.3 Mockito简介

Mockito是一个强大的Java模拟(Mocking)框架,用于单元测试中模拟依赖对象的行为。

特点

  • 模拟依赖对象,隔离被测代码。
  • 提供验证机制,检查方法是否按预期被调用。
  • 集成Spring和JUnit,简化测试编写。

核心方法

  1. mock(Class<T>):创建Mock对象。
  2. when(...).thenReturn(...):指定Mock行为。
  3. verify(...):验证调用情况。

示例代码:

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;class ServiceTest {@Testvoid testService() {MyRepository mockRepo = mock(MyRepository.class);when(mockRepo.findData()).thenReturn("Mocked Data");Service service = new Service(mockRepo);String result = service.getData();assertEquals("Mocked Data", result);verify(mockRepo).findData(); // 验证方法调用}
}

2. Spring Boot应用的单元测试与集成测试
2.1 单元测试的场景与工具

在Spring Boot中,单元测试通常用于验证Service层Repository层的逻辑,目标是隔离外部依赖。
Spring Boot推荐使用以下工具组合:

  • JUnit 5:编写和执行测试。
  • Mockito:模拟依赖对象。
  • Spring Test模块:集成Spring容器。

示例:测试Service层

引入Maven依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

示例代码:

@SpringBootTest
class UserServiceTest {@MockBeanprivate UserRepository userRepository;@Autowiredprivate UserService userService;@Testvoid testGetUserById() {User mockUser = new User(1L, "Alice");when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser));User result = userService.getUserById(1L);assertEquals("Alice", result.getName());}
}

说明

  • @MockBean:为测试创建Mock对象,并注入到Spring上下文。
  • @SpringBootTest:加载Spring上下文环境。

2.2 集成测试的场景与工具

集成测试通常用于验证多个模块的交互,比如Controller与Service层、Service与数据库的交互。
Spring Boot提供了一套强大的测试支持,主要工具和注解包括:

  • @SpringBootTest:加载完整的Spring上下文。
  • @Transactional:保证测试数据在测试后回滚。
  • TestRestTemplate:测试HTTP请求和响应。

示例:测试Controller层

  1. 创建Controller和对应的集成测试:
@RestController
@RequestMapping("/users")
class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public ResponseEntity<User> getUser(@PathVariable Long id) {return ResponseEntity.ok(userService.getUserById(id));}
}@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {@Autowiredprivate TestRestTemplate restTemplate;@Testvoid testGetUser() {ResponseEntity<User> response = restTemplate.getForEntity("/users/1", User.class);assertEquals(HttpStatus.OK, response.getStatusCode());}
}

3. MockMvc与测试Web层

MockMvc是Spring提供的用于测试Web层的工具,无需启动整个Spring容器即可测试Controller的行为。
它可以模拟HTTP请求并验证Controller的响应。

3.1 配置MockMvc
  1. 使用@WebMvcTest加载Controller的上下文:
@WebMvcTest(UserController.class)
class UserControllerMockMvcTest {@Autowiredprivate MockMvc mockMvc;@MockBeanprivate UserService userService;@Testvoid testGetUser() throws Exception {User mockUser = new User(1L, "Alice");when(userService.getUserById(1L)).thenReturn(mockUser);mockMvc.perform(get("/users/1")).andExpect(status().isOk()).andExpect(jsonPath("$.name").value("Alice"));}
}
3.2 MockMvc核心方法
  • perform():发送请求。
  • andExpect():断言响应结果。
  • jsonPath():验证JSON响应内容。

总结

通过本文的学习,开发者可以掌握如何在Spring Boot项目中高效地进行单元测试和集成测试:

  1. 单元测试侧重于模块逻辑验证,利用Mockito和JUnit简化依赖处理。
  2. 集成测试专注于模块交互,使用Spring Boot测试模块验证完整功能。
  3. MockMvc工具则为Web层测试提供了高效的解决方案。

这些测试工具和方法不仅能提高代码质量,还能在实际开发中帮助团队快速定位问题,减少后期维护成本。

关于作者:

15年互联网开发、带过10-20人的团队,多次帮助公司从0到1完成项目开发,在TX等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。本人开发期间收集了很多开发课程等资料,需要可联系我

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

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

相关文章

路径规划之启发式算法之二十八:候鸟优化算法(Migrating Birds Optimization, MBO)

候鸟优化算法(Migrating Birds Optimization, MBO)是一种基于群体智能的元启发式优化算法,其灵感来源于候鸟迁徙时的“V”字形飞行队列。这种队列结构能够有效减少能量消耗,同时提高飞行效率。MBO算法通过模拟候鸟的迁徙行为,利用群体间的协作和信息共享来优化问题的解。 …

Observability:最大化可观察性 AI 助手体验的 5 大提示(prompts)

作者&#xff1a;来自 Elastic Zoia_AUBRY 在过去三年担任客户工程师期间&#xff0c;我遇到了数百名客户&#xff0c;他们最常问的问题之一是&#xff1a;“我的数据在 Elastic 中&#xff1b;我该如何利用它获得最大优势&#xff1f;”。 如果这适用于你&#xff0c;那么本…

C# 委托和事件思维导图

思维导图 下载链接腾讯云盘 https://share.weiyun.com/fxBH9ESl

2024.ailx10的年终总结

已经工作7年啦&#xff0c;今年网络安全行业愈发寒冷&#xff0c;几乎所有友商都在做安全GPT&#xff0c;说实话&#xff0c;AI确实颠覆了传统的网络安全运营&#xff0c;以前需要安服处置告警&#xff0c;以后可能就不需要了&#xff0c;大家日子都不好过&#xff0c;越是简单…

机器学习(5):支持向量机

1 介绍 支持向量机&#xff08;Support Vector Machine&#xff0c;简称 SVM&#xff09;是一种监督学习算法&#xff0c;主要用于分类和回归问题。SVM 的核心思想是找到一个最优的超平面&#xff0c;将不同类别的数据分开。这个超平面不仅要能够正确分类数据&#xff0c;还要使…

AI需要的基础数学知识

AI&#xff08;人工智能&#xff09;涉及多个数学领域&#xff0c;以下是主要的基础数学知识&#xff1a; 1. 线性代数 矩阵与向量&#xff1a;用于表示数据和模型参数。矩阵乘法&#xff1a;用于神经网络的前向传播。特征值与特征向量&#xff1a;用于降维和主成分分析&…

flutter跨端UI框架简介

flutter跨端UI框架简介 简介 Flutter是由Google开发的开源应用开发框架&#xff0c;主要用于构建高性能、跨平台的移动、Web和桌面应用程序。Flutter使用Dart语言&#xff0c;提供了一套丰富的Widgets&#xff0c;使开发者能够快速创建美观的用户界面。其最大特点是热重载功能…

找不到mfc140u,具体原因分析

mfc140u.dll 是 Microsoft Foundation Classes (MFC) 库的一部分&#xff0c;通常与使用 MFC 构建的应用程序一起分发。当应用程序尝试运行但找不到 mfc140u.dll 时&#xff0c;可能的原因包括但不限于以下几点&#xff1a; 1.文件缺失&#xff1a; •可能是在安装或更新过程中…

StarRocks 3.4 发布--AI 场景新支点,Lakehouse 能力再升级

自 StarRocks 3.0 起&#xff0c;社区明确了以 Lakehouse 为核心的发展方向。Lakehouse 的价值在于融合数据湖与数据仓库的优势&#xff0c;能有效应对大数据量增长带来的存储成本压力&#xff0c;做到 single source of truth 的同时继续拥有极速的查询性能&#xff0c;同时也…

[答疑]这个消息名是写发送数据还是接收数据

睡鱼(61***11) 16:08:29 睡鱼(61***11) 16:08:58 他们说这个图有问题 UML菜鸟(1***22) 16:10:55 有点暗 睡鱼(61***11) 16:27:50 顺序图里面的箭头代表消息还是职责 睡鱼(61***11) 16:28:08 比如 a往b发送数据 睡鱼(61***11) 16:28:36 这个消息名是写发送数据还是接收数据 睡…

WPS按双字段拆分工作表到独立工作簿-Excel易用宝

我们老板真是事多&#xff0c;他说要把这个工作表以月份和支付方式的维度&#xff0c;以这两个字段进行拆分工作表&#xff0c;而且拆分出来的表格要保存一个新的工作簿。 啥事都交给我&#xff0c;他还以为我有三头六臂呢&#xff0c;还好我有易用宝&#xff0c;可以轻松拆分…

Linux——信号量和(环形队列消费者模型)

Linux——线程条件变量&#xff08;同步&#xff09;-CSDN博客 文章目录 目录 文章目录 前言 一、信号量是什么&#xff1f; 二、信号量 1、主要类型 2、操作 3、应用场景 三、信号量函数 1、sem_init 函数 2、sem_wait 函数 3、sem_post 函数 4、sem_destroy 函数 ​​​​​​…

Github 2025-01-20 开源项目周报 Top15

根据Github Trendings的统计,本周(2025-01-20统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10Rust项目2TypeScript项目1C++项目1Jupyter Notebook项目1Go项目1Tabby: 自托管的AI编码助手 创建周期:310 天开发语言:Rust协议类…

【分布式架构设计理论1】架构设计的演进过程

文章目录 一. 分布式架构要解决的问题二. 架构设计的演进过程1. 应用与数据一体2. 应用与数据分离3. 添加缓存&#xff1a;突破数据库&#xff08;IO&#xff09;瓶颈4. 服务器集群处理并发5. 数据库读写分离&#xff1a;释放读性能5.1. 问题分析5.2. 解决方案&#xff1a;读写…

【数据分享】1929-2024年全球站点的逐年最低气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff01;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2024年全球气象站点…

数据结构-ArrayList和顺序表

1.线性表 线性表是n个具有相同类型的数据元素所组成的有限序列&#xff0c;当n0时&#xff0c;线性表为一个空表。 常见的线性表&#xff1a;顺序表&#xff0c;链表&#xff0c;栈和队列... 线性表在逻辑上是线性结构&#xff0c;可以说是连续的一条直线。但是在物理结构上…

C#使用WMI获取控制面板中安装的所有程序列表

C#使用WMI获取控制面板中安装的所有程序列表 WMI 全称Windows Management Instrumentation,Windows Management Instrumentation是Windows中用于提供共同的界面和对象模式以便访问有关操作系统、设备、应用程序和服务的管理信息。如果此服务被终止&#xff0c;多数基于 Windo…

CPU狂飙900%如何分析?怎么定位?怎么溯源处理

当你的服务器CPU飙升到900%&#xff0c;系统卡顿、响应迟缓、业务受阻&#xff0c;这种令人焦虑的场景是否让你束手无策&#xff1f;别慌&#xff0c;这并不是世界末日&#xff0c;只要掌握正确的分析与定位方法&#xff0c;就能快速找到问题根源&#xff0c;并有效解决。 CPU…

第五篇 vue3 ref 与 reactive 对比

ref 若需要自动加载 .value ,那么就要在 底部 菜单 中 设置 选项 选择 vue 勾选 &#xff1a; Auto Insert: Dot Value Auto-complete Ref value with .value. 注意点&#xff1a; ref 不能写越过 value. 必须要在valeu 前面 进行定义 通过 reactive 来修改整体名称…

“大模型横扫千军”背后的大数据挖掘--浅谈MapReduce

文章目录 O 背景知识1 数据挖掘2 邦费罗尼原则3 TF.IDF4 哈希函数5 分布式文件系统 一、MapReduce基本介绍1. Map 任务2. 按键分组3. Reduce 任务4. 节点失效处理5.小测验&#xff1a;在一个大型语料库上有100个map任务和若干reduce任务&#xff1a; 二、基于MapReduce的基本运…