Spring Boot Test 的详细使用教程
Spring Boot Test 是 Spring Boot 提供的一个强大测试框架,用于帮助开发者简化和加速应用程序的单元测试和集成测试。下面是对 Spring Boot Test 各种测试类型和主要注解的详细教程。
1. Spring Boot Test 的基础概念
Spring Boot 提供了多种不同层次的测试工具,主要分为以下几类:
- 单元测试:用于测试单个类的功能,通常会隔离外部依赖,使用 Mockito 等框架来模拟。
 - 集成测试:测试多个组件协同工作的情况,通常会启动部分或全部 Spring 上下文。
 - 端到端测试:测试完整的应用,包括数据库等所有依赖。
 
Spring Boot Test 框架的核心依赖是 spring-boot-starter-test,它包含了多种测试框架,如 JUnit、Mockito、AssertJ、Hamcrest 和 JSONassert 等。
2. Spring Boot Test 常用注解
2.1 @SpringBootTest
@SpringBootTest 是 Spring Boot 提供的核心注解,适用于大多数集成测试。它可以启动完整的 Spring 上下文,模拟一个真实的应用程序环境。
示例:
@SpringBootTest
public class MyApplicationTests {
    @Autowired
    private SomeService someService;
    @Test
    public void testServiceMethod() {
        assertNotNull(someService);
    }
}
常用属性:
classes:指定要加载的应用上下文类,通常是主应用类。webEnvironment:指定 Web 环境类型,可以是NONE、MOCK、RANDOM_PORT或DEFINED_PORT。
例如,如果我们要在随机端口启动 Web 服务器:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebApplicationTests {
    // 测试代码
}
2.2 @MockBean 和 @SpyBean
@MockBean 和 @SpyBean 是 Spring Boot 提供的两个注解,允许你在测试时模拟和监控 Bean 行为。@MockBean 可以模拟依赖,而 @SpyBean 则会部分使用真实对象。
示例:
@SpringBootTest
public class MyServiceTests {
    @MockBean
    private SomeDependency someDependency;
    @Autowired
    private SomeService someService;
    @Test
    public void testSomeMethod() {
        when(someDependency.someMethod()).thenReturn("mocked result");
        assertEquals("mocked result", someService.someMethod());
    }
}
2.3 @DataJpaTest
@DataJpaTest 是专门为 JPA 相关测试提供的注解。它会配置一个内存数据库(如 H2),并只加载与 JPA 相关的 Bean。
示例:
@DataJpaTest
public class UserRepositoryTests {
    @Autowired
    private UserRepository userRepository;
    @Test
    public void testSaveAndFind() {
        User user = new User("testUser");
        userRepository.save(user);
        User foundUser = userRepository.findByUsername("testUser");
        assertEquals("testUser", foundUser.getUsername());
    }
}
2.4 @WebMvcTest
@WebMvcTest 用于测试 Web 层(通常是 Controller),不加载 Service 和 Repository 层。适合测试请求到 Controller 的映射和验证等。
示例:
@WebMvcTest(SomeController.class)
public class SomeControllerTests {
    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private SomeService someService;
    @Test
    public void testGetMethod() throws Exception {
        when(someService.getSomeData()).thenReturn("mock data");
        mockMvc.perform(get("/some-endpoint"))
               .andExpect(status().isOk())
               .andExpect(content().string("mock data"));
    }
}
2.5 @JsonTest
@JsonTest 用于测试 JSON 序列化和反序列化过程。它会加载 JSON 相关的 Bean,如 ObjectMapper。
示例:
@JsonTest
public class JsonSerializationTests {
    @Autowired
    private JacksonTester<MyObject> json;
    @Test
    public void testSerialize() throws IOException {
        MyObject myObject = new MyObject("value");
        assertThat(this.json.write(myObject)).isEqualToJson("expected.json");
    }
}
3. 测试中的 MockMVC 用法
MockMvc 是 Spring 提供的一个测试工具,用于模拟 HTTP 请求并验证响应。它可以搭配 @WebMvcTest 注解使用,也可以在 @SpringBootTest 环境下手动创建。
示例:
@SpringBootTest
@AutoConfigureMockMvc
public class WebApplicationTests {
    @Autowired
    private MockMvc mockMvc;
    @Test
    public void testEndpoint() throws Exception {
        mockMvc.perform(get("/api/hello"))
               .andExpect(status().isOk())
               .andExpect(content().string("Hello World"));
    }
}
4. 测试数据的准备和清理
在测试中,通常需要一些初始化数据,Spring Boot 提供了 @Sql 注解,可以在测试开始时运行 SQL 脚本,此外 @Transactional 注解可以在每次测试结束后自动回滚数据。
示例:
@SpringBootTest
@Transactional
@Sql(scripts = "/test-data.sql")
public class TransactionalTests {
    @Autowired
    private UserRepository userRepository;
    @Test
    public void testFindUser() {
        User user = userRepository.findByUsername("testUser");
        assertNotNull(user);
    }
}
5. 测试配置的分离
如果需要为不同环境提供不同的测试配置,可以使用 @ActiveProfiles 注解,指定要加载的配置文件。
示例:
@SpringBootTest
@ActiveProfiles("test")
public class ProfileBasedTests {
    @Autowired
    private SomeService someService;
    @Test
    public void testServiceMethod() {
        assertNotNull(someService);
    }
}
6. 测试 RestTemplate
如果你的应用依赖 RestTemplate 进行外部 API 调用,可以使用 MockRestServiceServer 模拟外部服务。
示例:
@SpringBootTest
public class RestTemplateTests {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RestTemplateBuilder restTemplateBuilder;
    private MockRestServiceServer mockServer;
    @BeforeEach
    public void setup() {
        this.mockServer = MockRestServiceServer.createServer(restTemplate);
    }
    @Test
    public void testRestTemplate() {
        this.mockServer.expect(requestTo("/some-api"))
                .andRespond(withSuccess("response", MediaType.APPLICATION_JSON));
        String response = restTemplate.getForObject("/some-api", String.class);
        assertEquals("response", response);
    }
}
7. 总结
以上介绍了 Spring Boot Test 的主要功能和用法,通常可以从以下几步开始:
- 单元测试:使用 
@MockBean和Mockito等工具模拟依赖。 - 集成测试:使用 
@SpringBootTest运行完整的应用上下文。 - Web 层测试:使用 
@WebMvcTest和MockMvc。 - 数据库测试:使用 
@DataJpaTest测试 JPA 层。 - 配置分离:使用 
@ActiveProfiles指定不同环境配置。 
掌握这些工具和注解后,可以覆盖 Spring Boot 应用的绝大部分功能测试需求。
                    
                
                
            
        
浙公网安备 33010602011771号