【单元测试】SpringBoot
1. 为什么单元测试很重要?‼️
从前,有一个名叫小明的程序员,他非常聪明,但有一个致命的缺点:懒惰。小明的代码写得又快又好,但他总觉得单元测试是一件麻烦事,觉得代码能跑就行,测试什么的全是浪费时间。
有一天,小明接到了一个重要的项目,他需要为一个在线购物网站开发一个新功能:用户可以在结账时使用优惠券。小明想:“这还不简单?半小时搞定!”于是,他迅速写好了代码,迫不及待地提交了。
第二天,项目经理来了,满脸怒气地对小明说:“小明,你的代码出问题了!所有用户在使用优惠券时都得到了负数的折扣,他们的账户反而被扣了更多的钱!”
小明惊讶地张大了嘴巴,不敢相信自己会犯这么低级的错误。他连忙检查代码,发现确实在计算折扣时,忘记处理负数的情况。小明赶紧修复了这个错误,但心里还是觉得不服气:“这只是个小问题,我不需要写单元测试。”
几天后,小明又收到一个新任务:实现一个积分系统,用户每消费一元就能积一分。小明想:“这次我一定不会犯错。”于是,他又快速写好了代码,提交了上去。
然而,不久之后,客户打电话过来抱怨:“我的积分怎么越消费越少了?!”
小明再次检查代码,发现自己在积分计算的函数里不小心多写了一个减号,导致积分被扣除而不是增加。他这次终于意识到,如果自己早点写单元测试,这些问题完全可以在开发阶段就被发现,而不是在上线后被用户发现。
于是,小明决定改过自新,认真学习单元测试。他发现,单元测试不仅可以帮助他捕捉到代码中的错误,还能让他更加自信地进行代码重构和优化。
总结
-
🔍早期发现问题:单元测试能够在开发阶段及时发现代码中的错误,避免错误在后期被发现,减少修复成本。
-
🐛确保代码质量:通过编写单元测试,可以验证每个模块的功能是否按预期工作,提升代码的可靠性和稳定性。
-
🔨方便重构:在进行代码重构或优化时,有单元测试作为保障,可以放心地修改代码,而不必担心引入新的错误
-
📄文档作用:单元测试可以作为代码的活文档,帮助新成员快速理解代码的功能和使用方法
2. 快速入门
2.1 基础配置
在 pom.xml 中添加以下依赖:
<dependencies>
<!-- Spring Boot Starter Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
这个依赖包含了多个库和功能,主要有以下几个:
- JUnit:JUnit是Java中最流行和最常用的单元测试框架,它提供了一套注解和断言来编写和运行单元测试。例如@Test注解表示一个测试方法,assertEquals断言表示两个值是否相等。
- Spring Test:Spring Test是一个基于Spring的测试框架,它提供了一套注解和工具来配置和管理Spring上下文和Bean。例如@SpringBootTest注解表示一个集成测试类,@Autowired注解表示自动注入一个Bean。
- Mockito:Mockito是一个Java中最流行和最强大的Mock对象库,它可以模拟复杂的真实对象行为,从而简化测试过程。例如@MockBean注解表示创建一个Mock对象,when方法表示定义Mock对象的行为。
- Hamcrest:Hamcrest是一个Java中的匹配器库,它提供了一套语义丰富而易读的匹配器来进行结果验证。例如assertThat断言表示验证一个值是否满足一个匹配器,is匹配器表示两个值是否相等。
- AssertJ:AssertJ是一个Java中的断言库,它提供了一套流畅而直观的断言语法来进行结果验证。例如assertThat断言表示验证一个值是否满足一个条件,isEqualTo断言表示两个值是否相等。
除了以上这些库外,spring-boot-starter-test还包含了其他一些库和功能,如JsonPath、JsonAssert、XmlUnit等。这些库和功能可以根据不同的测试场景进行选择和使用。
Mockito详解地址:https://pdai.tech/md/develop/ut/dev-ut-x-mockito.html
2.2 编写单元测试
为了更好的演示如何编写单元测试,以最简单的用户登录为例🌰
项目结构
src
├── main
│ └── java
│ └── com
│ └── hwq
│ └── fuwork01
│ ├── common
│ ├── controller
│ │ └── UserController.java
│ ├── dto
│ ├── exception
│ └── service
│ └── UserService
└── test
└── java
└── com
└── hwq
└── fuwork01
├── controller
│ └── UserControllerTest.java
└── service
└──FuWork01ApplicationTests.java
UserServiceImpl(Service层)
/**
* @author wqh
* @description 针对表【user(用户表)】的数据库操作Service实现
* @createDate 2024-07-15 17:13:27
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>