单元测试

依赖

<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

配合 @AutoConfigureMockMvcMockMvc 直接发请求断言响应:

@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 替换遗漏。

笔记加载中…