Spring系列---SpringBoot配置-profiles

本文介绍了Spring框架中Profiles的概念及其作用,展示了如何通过不同的profile配置开发、上线和测试环境,例如设置不同端口(8080、8081、8082)。同时,讲解了如何通过`spring.profiles.active`激活特定的profile,实现环境参数的隔离与管理。

1.profiles的作用

在这里插入图片描述

2.使用profiles

---
#开发环境
server:
  port: 8080
spring:
  profiles: dev #profile别名

---
#上线环境
server:
  port: 8081
spring:
  profiles: pro #profile别名
---
#测试环境
server:
  port: 8082
spring:
  profiles: test #profile别名
---
spring:
  profiles:
    active: test #指定使用哪个profile的配置参数

在这里插入图片描述

<think>我们使用JUnit 5和`spring-boot-starter-test`进行Spring Boot应用的测试。以下内容将分为几个部分: ### 一、`spring-boot-starter-test` 依赖配置 在`pom.xml`中添加依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> ``` 该依赖包含: - JUnit 5 - Spring Test - AssertJ - Mockito - JSONAssert - JsonPath ### 二、常用测试场景及注解 #### 1. 单元测试(不启动Spring上下文) 使用Mockito模拟依赖: ```java import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.BDDMockito.*; @ExtendWith(MockitoExtension.class) public class UserServiceTest { @Mock private UserRepository userRepository; @InjectMocks private UserService userService; // 自动注入模拟依赖 @Test void getUserByIdTest() { // 模拟行为 given(userRepository.findById(1L)).willReturn(new User(1L, "Alice")); // 调用方法 User user = userService.getUserById(1L); // 断言 assertEquals("Alice", user.getName()); } } ``` #### 2. Web层测试(使用`@WebMvcTest`) 仅加载Controller层: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @WebMvcTest(UserController.class) public class UserControllerTest { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; @Test void getUserTest() throws Exception { given(userService.getUserById(1L)).willReturn(new User(1L, "Alice")); mockMvc.perform(get("/users/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name").value("Alice")); } } ``` #### 3. 完整集成测试(使用`@SpringBootTest`) 启动整个Spring上下文: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class UserControllerIntegrationTest { @Autowired private TestRestTemplate restTemplate; @Test void getUserTest() { ResponseEntity<User> response = restTemplate.getForEntity("/users/1", User.class); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals("Alice", response.getBody().getName()); } } ``` ### 三、核心注解说明 | 注解 | 用途 | |------|------| | `@SpringBootTest` | 启动完整Spring上下文(可指定端口) | | `@WebMvcTest` | 仅加载Controller层组件 | | `@MockBean` | 在Spring上下文中替换Bean为Mock对象 | | `@DataJpaTest` | 仅加载JPA相关组件 | | `@JsonTest` | 测试JSON序列化 | | `@TestPropertySource` | 指定测试配置文件 | ### 四、测试最佳实践 1. **分层测试**: - 单元测试:直接测试类方法(不启动Spring- 切片测试:如`@WebMvcTest`(部分启动) - 集成测试:`@SpringBootTest`(完整启动) 2. **避免启动完整上下文的场景**: - 纯逻辑测试(无依赖) - 使用Mockito模拟外部依赖[^3] 3. **测试数据库交互**: ```java @DataJpaTest public class UserRepositoryTest { @Autowired private TestEntityManager entityManager; @Autowired private UserRepository repository; @Test void findByUsernameTest() { entityManager.persist(new User("Alice")); User user = repository.findByUsername("Alice"); assertNotNull(user); } } ``` ### 五、常见问题解决 **问题:测试时出现`NoSuchBeanDefinitionException`** - 原因:测试未扫描到Bean - 解决方案: ```java @SpringBootTest(classes = {MyApplication.class}) // 指定主配置类 ``` **问题:如何跳过Spring Security认证** ```java @WebMvcTest @AutoConfigureMockMvc(addFilters = false) // 禁用过滤器 public class TestControllerTest { ... } ``` ### 六、测试覆盖范围 使用Jacoco生成测试覆盖率报告: ```xml <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> ``` > 执行`mvn test`后查看`target/site/jacoco/index.html` --- §§相关问题§§ 1. 如何在测试中覆盖不同的Spring Profiles2. 如何测试Spring Boot Actuator端点? 3. 如何模拟RestTemplate调用的外部服务? 4. 测试事务如何自动回滚? </think> # 使用 spring-boot-starter-test 进行 Spring Boot 应用测试 `spring-boot-starter-test` 是 Spring Boot 提供的测试启动器,它集成了 JUnit、Mockito、AssertJ 等测试工具,为 Spring Boot 应用提供全面的测试支持。 ## 一、依赖配置 在 `pom.xml` 中添加依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> ``` 该依赖包含: - JUnit 5(Jupiter) - Spring Test & Spring Boot Test - Mockito - AssertJ - Hamcrest - JSONassert - JsonPath ## 二、核心测试注解 ### 1. 单元测试(不启动 Spring 上下文) ```java import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; @ExtendWith(MockitoExtension.class) class UserServiceTest { @Mock private UserRepository userRepository; @InjectMocks private UserService userService; @Test void getUserByIdTest() { // 模拟行为 when(userRepository.findById(1L)).thenReturn(Optional.of(new User(1L, "Alice"))); // 调用方法 User user = userService.getUserById(1L); // 断言 assertNotNull(user); assertEquals("Alice", user.getName()); } } ``` ### 2. Web 层测试(使用 `@WebMvcTest`) ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @WebMvcTest(UserController.class) class UserControllerTest { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; @Test void getUserByIdTest() throws Exception { // 模拟行为 given(userService.getUserById(1L)).willReturn(new User(1L, "Alice")); // 执行请求并验证 mockMvc.perform(get("/users/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name").value("Alice")); } } ``` ### 3. 集成测试(使用 `@SpringBootTest`) ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class UserControllerIntegrationTest { @Autowired private TestRestTemplate restTemplate; @Test void getUserByIdTest() { // 直接调用真实端点 ResponseEntity<User> response = restTemplate.getForEntity("/users/1", User.class); // 验证响应 assertEquals(200, response.getStatusCodeValue()); assertNotNull(response.getBody()); assertEquals("Alice", response.getBody().getName()); } } ``` ## 三、常用测试类型和注解 | 测试类型 | 注解 | 用途说明 | |----------------|----------------------|-----------------------------| | 单元测试 | `@ExtendWith(MockitoExtension.class)` | 不启动Spring上下文,纯Mock测试 | | Web切片测试 | `@WebMvcTest` | 只加载Controller层组件 | | JPA测试 | `@DataJpaTest` | 只加载JPA相关组件 | | JSON测试 | `@JsonTest` | 测试JSON序列化/反序列化 | | 完整集成测试 | `@SpringBootTest` | 启动完整Spring上下文 | | 配置测试 | `@TestConfiguration` | 定义测试专用配置 | ## 四、测试最佳实践 1. **分层测试策略**: - 单元测试:覆盖业务逻辑(70-80%) - 集成测试:验证组件集成(15-20%) - 端到端测试:验证完整流程(5-10%) 2. **避免完整启动的优化**: ```java // 对于不需要完整上下文的测试,使用轻量级方案 @WebMvcTest(UserController.class) public class LightweightControllerTest { // 只初始化Controller相关组件 } ``` 3. **测试数据库交互**: ```java @DataJpaTest public class UserRepositoryTest { @Autowired private TestEntityManager entityManager; @Autowired private UserRepository userRepository; @Test void findByUsernameTest() { // 准备测试数据 entityManager.persist(new User("Alice")); // 执行查询 User user = userRepository.findByUsername("Alice"); // 验证结果 assertNotNull(user); } } ``` 4. **使用测试配置文件**: ```java @SpringBootTest @TestPropertySource(locations = "classpath:application-test.properties") public class ProfileSpecificTest { // 使用测试专用的配置 } ``` ## 五、高级测试技巧 ### 1. 模拟 Spring Security 认证 ```java @WebMvcTest public class SecureControllerTest { @Autowired private MockMvc mockMvc; @Test @WithMockUser(username = "admin", roles = {"ADMIN"}) void adminEndpointTest() throws Exception { mockMvc.perform(get("/admin")) .andExpect(status().isOk()); } } ``` ### 2. 测试事务回滚 ```java @SpringBootTest @Transactional public class TransactionalTest { @Test @Rollback(true) // 默认回滚 void testWithRollback() { // 数据库操作会在测试后回滚 } } ``` ### 3. 自定义 MockMvc 配置 ```java @BeforeEach void setup() { mockMvc = MockMvcBuilders .webAppContextSetup(context) .apply(springSecurity()) // 启用Spring Security .alwaysDo(print()) // 总是打印请求/响应 .build(); } ``` ## 六、常见问题解决 1. **`NoSuchBeanDefinitionException` 错误**: - 确保使用 `@MockBean` 替代 `@Autowired` 的依赖 - 检查测试范围是否正确(如使用 `@WebMvcTest` 时不会加载Service组件) 2. **测试端口冲突**: ```java // 使用随机端口避免冲突 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) ``` 3. **测试性能优化**: - 对不需要启动完整上下文的测试使用 `@WebMvcTest` 或 `@DataJpaTest` - 使用 `@MockBean` 替代真实依赖注入 - 避免在单元测试中使用 `@SpringBootTest` > 参考:[Spring Boot Testing Documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值