【IDEA开发SpringBoot2.0】使用Mockito进行常规接口测试#05

本文介绍了Mockito框架在SpringBoot2.0项目中的应用,详细讲解了为何使用Mock代替真实对象进行测试,并对比了Mock与PostMan的区别。通过实例演示了如何创建Mockito测试,包括设置测试环境、编写测试代码以及解析测试结果,帮助读者理解Mockito在单元测试中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



前言1

什么是Mockito?

Mockito是GitHub上使用最广泛的Mock框架,并与JUnit结合使用.Mockito框架可以创建和配置mock对象.使用Mockito简化了具有外部依赖的类的测试开发!

什么是Mock?

在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的假的对象。程序员通常创造模拟对象来测试其他对象的行为,很类似汽车设计者使用碰撞测试假人来模拟车辆碰撞中人的动态行为。
也就是用来做程序测试的。

为什么要使用Mock?

因为有些时候,你很难再现真实的情况,例如:

真实对象的行为是不确定的(例如,当前的时间或当前的温度);
真实对象很难搭建起来;
真实对象的行为很难触发(例如,网络错误);
真实对象速度很慢(例如,一个完整的数据库,在测试之前可能需要初始化);
真实的对象是用户界面,或包括用户界面在内;
真实的对象使用了回调机制;
真实对象可能还不存在;
真实对象可能包含不能用作测试(而不是为实际工作)的信息和方法。

举一个简单的例子:如果你的程序需要传一个特定时间进行测试,你真的要等到那个时间吗?你不会这样做,而是模拟那个时间传过去

用PostMan与用Mock有什么区别?

经常做测试的肯定对PostMan都不陌生,PostMan是一个专门测试 API 的工具。
为什么我们要选用Mock做测试呢?
首先,PostMan相当于一个客户端(pm),在测试之前你需要先启动你的服务端(srever),相当于是一个客户端的测试
Mock是运行在服务端上的,Mock的作用就是模拟客户端的行为
区别在于Mock省去了网络请求的环节,提高了测试的效率
其次Mock是用编码实现的,PostMan是用真实的网络请求+客户端实现的
还有一个问题,我们在公司中一般都是自动化的单元测试,跑通之后自动打包发布,Mock可以实现但PostMan就不行了

正题

使用Mockito做一个模拟测试

编写代码

1.在Test目录的包下新建一个test包
在这里插入图片描述
在这里插入图片描述
2.创建一个MockitoTest类,代码如下

package com.moli.zy.springboot2ml.test;

import com.moli.zy.springboot2ml.controller.ArticleRestController;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot
### 如何在Spring Boot项目中使用Mockito进行单元测试 #### 1. 添加依赖 为了在Spring Boot项目中使用Mockito进行单元测试,首先需要确保`pom.xml`文件中有以下依赖项。此依赖项位于`spring-boot-starter-test`包中,它已经包含了Mockito和其他必要的库[^2]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> ``` #### 2. 创建待测类和服务层 假设有一个简单的服务类`EmployeeService`,其功能是从数据库获取员工数据并返回特定的结果: ```java @Service public class EmployeeService { private final EmployeeRepository employeeRepository; public EmployeeService(EmployeeRepository employeeRepository) { this.employeeRepository = employeeRepository; } public String getEmployeeNameById(int id) { Optional<Employee> optionalEmployee = employeeRepository.findById(id); return optionalEmployee.map(Employee::getName).orElse("Unknown"); } } ``` 这里还定义了一个接口`EmployeeRepository`用于访问数据库中的员工记录: ```java @Repository public interface EmployeeRepository extends JpaRepository<Employee, Integer> {} ``` #### 3. 编写单元测试 接下来编写针对`EmployeeService`的单元测试。通过Mockito模拟`EmployeeRepository`的行为来验证业务逻辑是否正常工作。 以下是完整的单元测试代码示例: ```java import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; class EmployeeServiceTest { @Mock private EmployeeRepository employeeRepository; @InjectMocks private EmployeeService employeeService; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); // 初始化Mock对象 } @Test void testGetEmployeeNameById_ExistingId() { int existingId = 1; Employee mockEmployee = new Employee(); mockEmployee.setName("John Doe"); when(employeeRepository.findById(existingId)).thenReturn(Optional.of(mockEmployee)); String result = employeeService.getEmployeeNameById(existingId); assertEquals("John Doe", result); verify(employeeRepository, times(1)).findById(existingId); } @Test void testGetEmployeeNameById_NonExistentId() { int nonExistentId = 999; when(employeeRepository.findById(nonExistentId)).thenReturn(Optional.empty()); String result = employeeService.getEmployeeNameById(nonExistentId); assertEquals("Unknown", result); verify(employeeRepository, times(1)).findById(nonExistentId); } } ``` 在这个例子中: - 使用了`@Mock`注解创建`EmployeeRepository`的模拟实例。 - `@InjectMocks`注解告诉Mockito将模拟的对象注入到实际的服务实现中[^3]。 - 调用了`MockitoAnnotations.openMocks(this)`手动初始化这些Mock对象,在非Spring环境下这是必需的操作[^1]。 对于基于Spring Boot的应用程序,如果希望利用Spring容器管理Bean,则可以改用`@ExtendWith(SpringExtension.class)`以及`@MockBean`替代上述方式。 #### 4. 基于Spring Context的集成测试 当需要加载整个Spring应用上下文时,可以通过如下方式进行配置: ```java @SpringBootTest @AutoConfigureMockMvc class EmployeeServiceIntegrationTest { @Autowired private EmployeeService employeeService; @MockBean private EmployeeRepository employeeRepository; @Test void testGetEmployeeNameById_SpringContext() { int existingId = 1; Employee mockEmployee = new Employee(); mockEmployee.setName("Jane Smith"); when(employeeRepository.findById(existingId)).thenReturn(Optional.of(mockEmployee)); String result = employeeService.getEmployeeNameById(existingId); assertEquals("Jane Smith", result); verify(employeeRepository, times(1)).findById(existingId); } } ``` 在这里,`@MockBean`由Spring Test框架提供支持,能够更方便地替换掉真实的Bean实例,并且无需显式调用`openMocks()`方法[^1]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值