当前位置: 首页 > news >正文

SpringBoot JUnit 教程

1. 核心依赖 (Maven)

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

该 Starter 自动引入:

  • JUnit 5(Jupiter)

  • Mockito

  • AssertJ

  • Spring Test


2. 基础注解

注解作用
@SpringBootTest启动完整 Spring 上下文(集成测试)
@Test标记测试方法
@BeforeEach/@AfterEach每个测试前/后执行
@BeforeAll/@AfterAll所有测试前/后执行(需静态方法)
@DisplayName给测试起中文名
@Disabled禁用测试

3. 单元测试(Service 层)

被测 Service:

@Service public class UserService { public String getUserName(Long id) { return "user-" + id; } }

测试类:

@SpringBootTest class UserServiceTest { @Autowired private UserService userService; @Test @DisplayName("根据ID获取用户名") void testGetUserName() { String name = userService.getUserName(1L); assertEquals("user-1", name); assertNotNull(name); } }

4. Web 层测试(Controller)

使用@WebMvcTest只加载 Web 层,比@SpringBootTest轻量。

被测 Controller:

@RestController @RequestMapping("/api/users") public class UserController { @GetMapping("/{id}") public String getUser(@PathVariable Long id) { return "user-" + id; } }

测试类:

@WebMvcTest(UserController.class) class UserControllerTest { @Autowired private MockMvc mockMvc; @Test void testGetUser() throws Exception { mockMvc.perform(get("/api/users/1")) .andExpect(status().isOk()) .andExpect(content().string("user-1")); } }

5. Mock 依赖(隔离测试)

使用@MockBean模拟 Service,避免依赖真实数据库。

@SpringBootTest class UserControllerMockTest { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; @Test void testGetUser() throws Exception { when(userService.getUserName(1L)).thenReturn("mock-user"); mockMvc.perform(get("/api/users/1")) .andExpect(status().isOk()) .andExpect(content().string("mock-user")); } }

6. 数据层测试(Repository)

使用@DataJpaTest测试 JPA,默认回滚事务。

@DataJpaTest class UserRepositoryTest { @Autowired private UserRepository userRepository; @Test void testSaveAndFind() { User user = new User("test"); userRepository.save(user); Optional<User> found = userRepository.findByName("test"); assertTrue(found.isPresent()); } }

7. 断言进阶(AssertJ)

import static org.assertj.core.api.Assertions.*; assertThat(user.getName()).startsWith("user"); assertThat(list).hasSize(3).contains("a", "b");

8. 测试生命周期

@TestInstance(TestInstance.Lifecycle.PER_CLASS) class LifecycleTest { @BeforeAll void initAll() { /* 无需 static */ } }

9. 常用 Mockito 操作

// 验证调用次数 verify(userService, times(1)).getUserName(anyLong()); // 抛出异常 when(userService.getUserName(1L)).thenThrow(new RuntimeException("error")); // 参数匹配 when(userService.getUserName(eq(1L))).thenReturn("user-1");

10. 测试覆盖率 (Jacoco)

<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.11</version> </plugin>

执行mvn clean test后生成target/site/jacoco/index.html


11. 最佳实践总结

类型推荐注解说明
单元测试(Service)@SpringBootTest可配合@MockBean
Web 层测试@WebMvcTest只加载 Controller
Repository 测试@DataJpaTest轻量,自动回滚
集成测试@SpringBootTest加载完整上下文
测试命名should_xxx_when_xxx清晰表达意图
断言AssertJ更丰富流畅

12. 面试常见问题

  1. @SpringBootTest@WebMvcTest区别?

    • @SpringBootTest:加载全部 Bean,适合集成测试。

    • @WebMvcTest:只加载 Web 层,更快。

  2. @MockBean@Mock区别?

    • @MockBean是 Spring 提供的,会将 Mock 对象注入 Spring 容器。

    • @Mock是 Mockito 的,不管理容器。

  3. 如何测试异步方法?
    使用@Async+CountDownLatchCompletableFuture配合await()

http://www.jsqmd.com/news/1132430/

相关文章:

  • Qt界面底层实现浅谈: 多渲染后端的分层架构
  • CAF 与 PDAF 监控机制对比:从 3 种检测逻辑到触发条件差异分析
  • 126、DyHead 动态检测头替换 YOLOv11 Head:Scale+Space+Task 三维注意力的实现
  • 宝鸡装修必看:安柏特全屋定制厂环保板材解析
  • 视频孪生时空感知技术详解
  • C# 基础入门指南:从零开始学习 C# 编程
  • XCA开源证书管理:如何用现代工具解决传统PKI难题
  • 【译】组织好你的Asp.Net MVC解决方案
  • 实战指南:如何将微信聊天记录转化为个人AI训练数据资产
  • NHibernate Issues之1255:联合主键(composite-id)
  • 该如何进行WPF界面设计
  • o1-preview在机器学习项目中的协同建模实战
  • 6款主流AI智能降重工具 降痕效果拉满
  • Claude Code Review实战:AI驱动的自动化代码审查部署与优化指南
  • 【Bug已解决】Claude Team Plan 购买席位报错 Payment failed 解决方案
  • 从 Demo 到可上线:一个游戏智能客服 RAG 系统的工程化拆解
  • 修改网口MTU说明
  • Claude Fable 5 实战方法论 | 八招解锁 Agentic Coding 最高效率
  • 推荐几个好用到哭的小清新APP
  • 再次探讨企业级开发中的Try......Catch性能问题
  • 2025年CSDN年度技术趋势预测:AI、云原生与开发者工具的未来
  • 想找靠谱的商用轨道插座源头厂家?这些实用挑选方法一定要收好
  • BetterNCM安装器:让网易云音乐插件安装变得像点外卖一样简单
  • day0203
  • RTL8723DU WiFi+蓝牙驱动移植对比:全志D1与Milk-V Duo 2平台实战解析
  • MSF 反弹 Shell 实战教程:从生成木马到获取服务器权限
  • 数据视图学习博客笔记(含数据表对比)
  • 5个VADER情感分析技巧:社交媒体情感分析终极指南
  • 01-PEFT源码阅读-项目总览与设计理念
  • dbus的如何使用教程以及相关概念