UserServiceMockitoTest

📅 发布时间:2026/10/9 1:41:18
UserServiceMockitoTest
测试类package com.example.demo;/** *Author:hw0089751 *Date:2025/10/9 */ import com.example.demo.mockitodemo.UserDTO; import com.example.demo.mockitodemo.UserService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.web.client.RestTemplate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * 一、ExtendWith注解 * ExtendWith 注解是 JUnit 5 中的一个扩展机制用于为测试类或测试方法提供扩展功能。 * 它的主要作用是注册一个或多个扩展Extension这些扩展可以在测试的生命周期中 执行额外的逻辑例如初始化、清理、拦截测试执行等。 * * 常见扩展 * 1.MockitoExtension * 提供 Mockito 的支持例如自动创建 Mock 对象。 * 2.SpringExtension * 集成 Spring 的测试功能例如加载 Spring 上下文。 * 3.TempDirectory * 提供临时目录支持用于文件操作测试。 * * 二、Mock注解 * Mock 注解是 Mockito 框架中的一个核心注解用于创建一个模拟对象Mock Object。 它的主要作用是替代真实对象 * 用于测试代码中的依赖关系从而隔离测试逻辑避免依赖外部系统或复杂的对象。 * * 作用 * 1.创建 Mock 对象 * Mock 会创建一个模拟对象模拟对象可以替代真实对象的行为。 * 通过 Mockito.when() 方法可以定义模拟对象的行为。 * 2.隔离测试 * 使用 Mock 可以避免测试依赖真实对象从而专注于测试目标代码的逻辑。 * 3.简化测试代码 * 通过注解方式创建 Mock 对象避免手动调用 Mockito.mock() 方法。 * 4.结合 InjectMocks 使用 * Mock 创建的模拟对象可以自动注入到被测试的类中简化依赖注入。 * * 三、Mock注解 * InjectMocks 是 Mockito 框架中的一个注解用于自动将标记为 Mock 或 Spy 的模拟对象Mock 或 Spy注入到被测试的类中。 * 它的主要作用是简化依赖注入过程避免手动创建和设置依赖。 * * 作用 * 1.自动注入依赖 * InjectMocks 会将标记为 Mock 或 Spy 的对象注入到被测试类的字段中。 * 支持构造函数注入、字段注入和 setter 方法注入。 * * 2.简化测试代码 * 避免手动创建被测试类的实例以及注入依赖提升代码可读性。 * * 3.结合 Mock 使用 * InjectMocks 通常与 Mock 一起使用Mock 创建的模拟对象会自动注入到被测试类中。 * */ // 启用Mockito扩展 ExtendWith(MockitoExtension.class) public class UserServiceMockitoTest { Mock private RestTemplate restTemplate; // 模拟RestTemplate依赖被测试的类内部依赖的类 InjectMocks private UserService userService; // 将模拟对象注入被测类被测试的类 Test void createUser_shouldReturnUserIdOnSuccess() { // 准备测试数据 UserDTO userDTO new UserDTO(testmail.com, Test User); // 配置模拟行为当调用postForObject方法时返回预设响应 String mockedResponse user-id-123; // when(restTemplate.postForObject( // eq(http://localhost:19001/users), // 使用实际URL // any(UserDTO.class), // 使用更宽松的匹配 // eq(String.class)) // 匹配响应类型 // ).thenReturn(mockedResponse); // 不要换行换行影响执行结果 when(restTemplate.postForObject(anyString(), any(),eq(String.class))).thenReturn(mockedResponse); // 调用被测方法 String userId userService.createUser(userDTO); // 验证结果 assertEquals(user-id-123, userId); // 验证方法调用细节 verify(restTemplate, times(1)) .postForObject(eq(http://localhost:19001/users), same(userDTO), eq(String.class)); } Test void createUser_shouldHandleServerErrors() { UserDTO requestUser new UserDTO(failmail.com, null); // 配置模拟行为抛出特定异常 when(restTemplate.postForObject( anyString(), same(requestUser), eq(String.class) )).thenThrow(new RuntimeException(Internal server error)); // 验证异常抛出 Exception ex assertThrows(RuntimeException.class, () - { userService.createUser(requestUser); }); assertEquals(Internal server error, ex.getMessage()); // verify(restTemplate).postForObject( // contains(/users), // URL包含特定字符 // argThat(u - u. null), // 参数自定义断言 // eq(String.class) // ); } }被测试相关类package com.example.demo.mockitodemo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * Author:hw0089751 * Date:2025/10/10 */ RestController public class UserController { Autowired private UserService userService; PostMapping(/getUser) public String createUser(RequestBody UserDTO user) { // 业务逻辑比如调用service return userService.createUser(user); } } package com.example.demo.mockitodemo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; /** * Author:hw0089751 * Date:2025/10/9 */ Service public class UserService { Autowired private RestTemplate restTemplate; private final String apiUrl http://localhost:19001/users; public String createUser(UserDTO userDto) { // POST请求创建用户 String result restTemplate.postForObject(apiUrl, userDto, String.class); return result; } } package com.example.demo.mockitodemo; /** * Author:hw0089751 * Date:2025/10/9 */ // 辅助数据传输类 public class UserDTO { private String email; private String name; public UserDTO(String email, String name) { this.email email; this.name name; } // getters省略 public String getEmail() { return email; } public void setEmail(String email) { this.email email; } public String getName() { return name; } public void setName(String name) { this.name name; } }