单元测试
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
该 starter 聚合了 JUnit 5(Jupiter)、Mockito、AssertJ、Hamcrest 等常用测试库(清单随版本微调,以官方文档为准)。Boot 4 对测试模块做了重组,个别测试切片注解可能需额外模块。
纯单元测试:不启动 Spring
业务逻辑与依赖无关时,写成普通 JUnit 测试,快而稳定:
import static org.assertj.core.api.Assertions.assertThat;
@Test
void add() {
assertThat(new Calculator().add(1, 2)).isEqualTo(3);
}
用 Mockito 隔离依赖
被测对象依赖 DAO、外部服务时,用 @Mock 打桩、@InjectMocks 注入:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserDao userDao;
@InjectMocks
private UserService userService;
@Test
void findByIdReturnsUser() {
when(userDao.findById(1L)).thenReturn(new User(1L, "张三", 18));
User user = userService.findById(1L);
assertThat(user.getName()).isEqualTo("张三");
verify(userDao).findById(1L); // 校验确有一次调用
}
}
核心 API:when(...).thenReturn(...) 预设返回值、verify(...) 校验调用、thenThrow 模拟异常。这类测试不启动 Spring 容器、速度最快,应占测试数量的大头。
集成测试:@SpringBootTest
需要真实装配(自动配置、数据库等)时启动整个上下文:
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void saveAndFind() {
User saved = userRepository.save(new User("李四", 20));
assertThat(userRepository.findById(saved.getId())).isPresent();
}
}
涉及数据库写入的测试可加 @Transactional 让每个用例自动回滚,互不污染。
Web 层测试:MockMvc
配合 @AutoConfigureMockMvc 用 MockMvc 直接发请求断言响应:
@SpringBootTest
@AutoConfigureMockMvc
class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void hello() throws Exception {
mockMvc.perform(get("/hello"))
.andExpect(status().isOk()).andExpect(content().string("Hello, Spring Boot!"));
}
}
MockMvc 不占真实端口;需要完整 HTTP 栈时改用 @SpringBootTest(webEnvironment = RANDOM_PORT) 配合 TestRestTemplate。
替换外部依赖:@MockitoBean
集成测试中切断真实外部依赖(邮件、第三方接口、Redis)时,用 @MockitoBean 替换容器里的 Bean:
@SpringBootTest
class MailServiceTest {
@MockitoBean
private JavaMailSender mailSender;
@Autowired
private MailService mailService;
@Test
void sendSimple() {
mailService.sendSimple("a@example.com", "主题", "内容");
verify(mailSender).send(any(SimpleMailMessage.class));
}
}
@MockitoBean/@MockitoSpyBean 自 Boot 3.4 起推荐使用;旧注解 @MockBean/@SpyBean 已废弃,Boot 4.0 中已被移除(4.x 里找不到 @MockBean 属正常现象)。
小结
测试金字塔自下而上:纯逻辑用 JUnit + Mockito 快速覆盖;@SpringBootTest 验证自动配置与组件协作;@MockitoBean 切断外部依赖。上下文起不来时先看启动日志,多半是外部依赖未就绪或 Bean 替换遗漏。