Spring单元测试(一)入门与实践
问题:如何快速测试,而不是每次测试都要重启应用?
目标:尽量只测试局部代码
不同的测试
软件工程中分为:单元测试、集成测试、功能测试、系统测试。其中功能测试和系统测试一般是测试人员的责任,但单元测试和集成测试则必须由开发人员保证。
- 功能测试:检查是否满足需求说明书中确定的各项需求。
- 系统测试:与系统其他功能组合在一起进行测试
- 单元测试:检查开发者编写的一小段代码,以确认改动是否正确。
一个功能往往会调用多个接口方法实现,在单元测试时,需要屏蔽掉这些外在接口方法的依赖,将测试焦点集中到目标功能代码上。比如改动了底层工具类 DateUtils 的公共方法。
这时模拟就是最有力的工具,模拟的是功能的使用过程,假定外在接口方法正常返回的情况下验证目标代码的正确性。常见的模拟工具有 EasyMock、JMock、Mockito。
单元测试最重要的是可重复性,不可重复性的单元测试是没有价值的。
单元测试和开发工作是同时进行的,有时候甚至是在开发工作之前。
- 集成测试则是在功能开发代码开发完成之后,验证功能模块之间是否能工正常调用。
比如,当对 UserService 这个业务层类进行单元测试时,可以通过创建 UserDao 模拟对象,假设 DAO 层接口方法正常工作的情况下对 UserService 进行局部单元测试。
而对 UserService 进行集成测试时,则应该注入真实的 UserDao 对象进行。
所以一般来讲,集成测试面向的层面更高一些,一般对业务层和 Web 层进行集成测试;单元测试则面向一些功能单一的类,比如字符串格式化工具类、数据计算类等。
测试框架
Spring-Test 是 springframework 中的一个模块,是 Spring 提供的单元测试套件,可以方便的测试基于 Spring 框架的代码。
Spring-Test 是 Spring 框架的扩展,它专门用于帮助测试 Spring 应用,构建在 Junit 基础上,提供 Spring 容器相关的功能,比如测试 Spring Bean 的生命周期、Spring 配置加载等。
代码实践
1、引入依赖
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.11.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.11.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
2、接口测试
/**
* Favor接口单元测试
*/
@RunWith(MockitoJUnitRunner.class)
public class FavorControllerTest {
private MockMvc mockMvc;
@Mock
private FavorService favorService;
@Mock
private PersonService personService;
@InjectMocks
private FavorController favorController;
@Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(favorController).build();
// 模拟登录用户
MockedStatic<SessionUtils> sessionUtils = mockStatic(SessionUtils.class);
User mockUser = new User();
mockUser.setId(1L);
mockUser.setUserName("testUser");
sessionUtils.when(SessionUtils::currentUser).thenReturn(mockUser);
}
/**
* 测试请求报文是否合法
*
* @throws Exception
*/
@Test
public void listPage_ValidQuery_ShouldReturnFavorList() throws Exception {
// 模拟查询结果
List<Favor> favorList = new ArrayList<>();
Favor favor = new Favor();
favor.setId(1L);
favor.setHoldPersonId(1L);
favorList.add(favor);
// 模拟业务层分页查询
when(favorService.findPage(any(PageQuery.class))).thenReturn(favorList);
// 模拟查询人员
Person mockPerson = new Person();
mockPerson.setId(1L);
when(personService.findById(1L)).thenReturn(mockPerson);
// 模拟Http请求
String requestBody = "{\"terms\":{\"title\":\"someValue\"},\"page\":{\"pageNo\":1,\"pageSize\":10}}";
mockMvc.perform(post("/favor/listPage")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpect(status().isOk());
}
}
为了行文简洁,忽略的 FavorController、FavorService 等部分代码的实现,不影响说明
注意:此代码是为了测试请求报文的合法性,即请求的响应码是否是 200,前提是接口在验证请求报文不合法时,会返回 200 以外的响应码。
不同的测试目标,代码也会不同。
3、DAO 层测试
/**
* DAO层测试
*/
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@Transactional
public class FavorItemDaoTest {
@Autowired
private FavorItemDao favorItemDao;
@Before
public void setUp() {
// 如果需要,可以在这里进行任何通用设置
}
/**
* 测试查询条件
*/
@Test
public void findByCondition_related() {
Map<String, Object> map = ImmutableMap.of("receiveGiveRelated", true,
"receivePersonIdList", Arrays.asList(1L, 2L, 3L, 4L),
"givePersonIdList", Arrays.asList(11L, 12L));
List<FavorItem> byCondition = favorItemDao.findByCondition(map);
assertNotEquals(0, byCondition.size());
}
}
这里的 Spring 配置文件建议尽量简洁,以加快测试方法执行。
Spring单元测试(一)入门与实践的更多相关文章
- Spring Reactor 入门与实践
适合阅读的人群:本文适合对 Spring.Netty 等框架,以及 Java 8 的 Lambda.Stream 等特性有基本认识,希望了解 Spring 5 的反应式编程特性的技术人员阅读. 一.前 ...
- ActiveMQ消息队列从入门到实践(4)—使用Spring JMS收发消息
Java消息服务(Java Message Service ,JMS)是一个Java标准,定义了使用消息代理的通用API .在JMS出现之前,每个消息代理都有私有的API,这就使得不同代理之间的消息代 ...
- Spring AOP初级——入门及简单应用
在上一篇<关于日志打印的几点建议以及非最佳实践>的末尾提到了日志打印更为高级的一种方式——利用Spring AOP.在打印日志时,通常都会在业务逻辑代码中插入日志打印的语句,这实际上是 ...
- Spring Mvc的入门
SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的. Spring Web MVC是什么: Sprin ...
- Spring Boot -01- 快速入门篇(图文教程)
Spring Boot -01- 快速入门篇(图文教程) 今天开始不断整理 Spring Boot 2.0 版本学习笔记,大家可以在博客看到我的笔记,然后大家想看视频课程也可以到[慕课网]手机 app ...
- ActiveMQ (三) Spring整合JMS入门
Spring整合JMS入门 前提:安装好了ActiveMQ ActiveMQ安装 Demo结构: 生产者项目springjms_producer: pom.xml <?xml versio ...
- Spring Cloud 从入门到精通
Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量. 本 ...
- 入门python:《Python编程从入门到实践》中文PDF+英文PDF+代码学习
入门python推荐学习久负盛名的python入门书籍<Python编程从入门到实践>. 书中涵盖的内容是比较精简的,没有艰深晦涩的概念,最重要的是每个小结都附带有"动手试一试& ...
- Spring Boot从入门到精通(九)整合Spring Data JPA应用框架
JPA是什么? JPA全称Java Persistence API,是Sun官方提出的Java持久化规范.是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. ...
- Spring Data JPA入门及深入
一:Spring Data JPA简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问 ...
随机推荐
- Element-Plus表格:Table自定义合并行数据的最佳实践
" 知行合一 " -- 王阳明 在开发项目中,我们时常会用到表格,许多需求可能会要求自定义特定的行或列. 接下来,我们将探讨在实际开发中如何应对这一挑战. 本文案例采用的技术: 名 ...
- docker构建supervisor镜像
1 介绍 记录使用docker 构建包含 supervior 的镜像, supervisor: 是一个管理和监控进程的程序,可以方便的通过配置文件来管理我们的任务脚本 将supervisor构建到系统 ...
- uniapp 使用pinpa 持续化更新
安装依赖 npm i pinia npm i pinia-plugin-persistedstate 新建 index.ts import { createPinia } from 'pinia' i ...
- 虚拟机 ubuntu18 树莓派4 QT5.14.2 交叉编译
编译过程主要参考了 <为树莓派4交叉编译QT5.14.2(带EGLFS支持)>,可以按照教程一步一步进行,在整个过程中,有2个地方需要注意. 1. sudo rpi-update 因为网络 ...
- Gitlab误删用户导致项目丢失莫慌
Gitlab让小朋友不小心把离职员工的账号给删了,可是离职员工有好几个项目都是他是owner,造成Gitlab上项目全部丢失. 遇到这种情况,莫慌. 一般,本地都有完整的Git备份,离职员工走了,肯定 ...
- 【C#】【平时作业】习题-4-流程控制
T1 创建一个Windows应用程序,先输入年龄值,再判断是否大于18,最后显示判断结果,运行效果如图所示. 提示: 注意保持逻辑完整: 引用数据需要明确出处. [程序代码] private void ...
- 【MyBatis】学习笔记13:延迟加载(懒加载)
目录 Mybatis13:延迟加载(懒加载) 测试 测试1 测试2 部分特殊情况处理 Mybatis13:延迟加载(懒加载) 延迟加载是分步查询的好处,默认是不开启延迟加载的,要开启需要在核心配置文件 ...
- Log4net的使用教程
不怎么爱写日志,(就是比较懒),后来遇上bug了找不到问题,才决定好好使用日志 其实说实话,log4配置的那些东西记不太住,但也不需要记住什么.百度就有现成的,自己跟着网上配置好之后,稍微记录一下,为 ...
- 网络编程入门如此简单(四):一文搞懂localhost和127.0.0.1
本文由萤火架构分享,原题"localhost和127.0.0.1的区别是什么?",原文链接"juejin.cn/post/7321049446443417638" ...
- new idea
如何我希望将url链接作为大语言模型的输入,同时通过大模型的能力来学习与认识url网页链接中的文本.图片.语音等元素,应该怎么做? 要将URL链接作为输入来学习与识别URL中的文本.图片.语音等元素, ...