JAVA:Spring Boot 集成 JUnit 进行单元测试

admin
3
2025-09-05

1、简述

在软件开发中,单元测试是确保代码质量和可维护性的关键步骤。JUnit作为Java领域最流行的单元测试框架之一,提供了简单而强大的测试工具,可以帮助开发者在项目开发过程中及时发现和修复代码中的问题。本文将介绍JUnit的基本用法以及一些高效的单元测试技巧,帮助开发者更好地应用JUnit进行单元测试。

image-cjla.png


2、为什么要写测试?

🔹 验证逻辑正确性:保证代码行为符合预期。

🔹 降低回归风险:代码迭代时能快速发现问题。

🔹 提升开发效率:避免频繁手动验证。

🔹 持续集成必备:结合 CI/CD 自动执行测试用例。

2.1 Maven 引用

Spring Boot 默认支持 JUnit 5(JUnit Jupiter),常用依赖如下:

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

该依赖包含了:

🔹 JUnit 5

🔹 Spring Test(集成测试支持)

🔹 Mockito(Mock 测试)

🔹 AssertJ / Hamcrest(断言工具)

2.2 常用测试注解

🔹 @SpringBootTest
启动整个 Spring Boot 上下文,常用于集成测试。

🔹 @Test
标记为 JUnit 测试方法。

🔹 @BeforeEach / @AfterEach
在每个测试方法前后执行,常用于准备/清理环境。

🔹 @MockBean
在 Spring 容器中注入一个 Mock 对象,替换真实 Bean。

🔹 @Autowired
注入需要测试的 Bean。


3、实践样例

3.1 测试 Service 层

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void testAddUser() {
        User user = new User("Tom", 20);
        User saved = userService.addUser(user);
        assertThat(saved.getId()).isNotNull();
        assertThat(saved.getName()).isEqualTo("Tom");
    }
}

3.2 使用 MockMvc 测试 Controller 层

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetUser() throws Exception {
        mockMvc.perform(get("/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("Tom"));
    }
}

3.3 使用 Mockito 模拟依赖

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.beans.factory.annotation.Autowired;
import static org.mockito.Mockito.when;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
public class OrderServiceTest {

    @MockBean
    private PaymentService paymentService;

    @Autowired
    private OrderService orderService;

    @Test
    void testCreateOrderWithMockPayment() {
        when(paymentService.pay(100)).thenReturn(true);

        boolean result = orderService.createOrder(100);

        assertThat(result).isTrue();
    }
}

3.4 测试 Repository 层(数据库)

Spring Boot 可以结合 H2 内存数据库做 Repository 测试。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void testSaveAndFindUser() {
        User user = new User("Jerry", 25);
        userRepository.save(user);

        User found = userRepository.findByName("Jerry");
        assertThat(found).isNotNull();
        assertThat(found.getAge()).isEqualTo(25);
    }
}

4、最佳实践

🔹 单元测试尽量隔离外部依赖
使用 Mockito Mock 掉第三方接口、数据库操作。

🔹 集成测试覆盖关键业务流程
使用 @SpringBootTest 启动完整环境。

🔹 分层测试
Service 层用 Mock 隔离依赖。
Controller 层用 MockMvc 模拟请求。
Repository 层结合 H2 测试数据库逻辑。

🔹 自动化执行
在 CI/CD 流水线中自动执行 mvn test


5、总结

通过上述简单的示例,我们可以看到JUnit提供了丰富而强大的功能,帮助开发者更好地进行单元测试。合理的单元测试不仅可以提高代码的可维护性,还有助于及早发现和解决潜在问题。通过JUnit,开发者能够更加自信地进行代码重构、功能更新等工作,确保软件的质量和稳定性。

🔹 Spring Boot 提供了完善的测试框架支持,依赖一个 spring-boot-starter-test 就能搞定。

🔹 我们可以灵活选择 单元测试(Mock)、集成测试(SpringBootTest)、数据库测试(H2)

🔹 合理编写测试用例,可以让项目在迭代中更加稳定、可维护。

动物装饰