跳到主要内容

测试

DeepSeek V3 中英对照 Testing

Spring Boot 包含了许多测试工具和支持类,以及一个专门的启动器,提供了常见的测试依赖。本节将回答关于测试的常见问题。

使用 Spring Security 进行测试

Spring Security 提供了支持以特定用户身份运行测试的功能。例如,下面代码片段中的测试将使用一个具有 ADMIN 角色的已认证用户来运行。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.assertj.MockMvcTester;

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

@WebMvcTest(UserController.class)
class MySecurityTests {

@Autowired
private MockMvcTester mvc;

@Test
@WithMockUser(roles = "ADMIN")
void requestProtectedUrlWithUser() {
assertThat(this.mvc.get().uri("/")).doesNotHaveFailed();
}

}
java

Spring Security 提供了与 Spring MVC Test 的全面集成,这在结合使用 @WebMvcTest 切片和 MockMvc 测试控制器时也同样适用。

有关 Spring Security 测试支持的更多详细信息,请参阅 Spring Security 的参考文档

结构 切片测试中包含的类

切片测试的工作原理是根据组件的类型,将 Spring Framework 的组件扫描限制在一组有限的组件范围内。对于那些不是通过组件扫描创建的 bean,例如使用 @Bean 注解创建的 bean,切片测试将无法在应用上下文中包含或排除它们。考虑以下示例:

import com.zaxxer.hikari.HikariDataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
return http.build();
}

@Bean
@ConfigurationProperties("app.datasource.second")
public HikariDataSource secondDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

}
java

对于一个使用了上述 @Configuration 类的应用程序进行 @WebMvcTest 测试时,你可能会期望应用程序上下文中包含 SecurityFilterChain bean,以便你可以测试控制器端点是否被正确保护。然而,MyConfiguration 不会被 @WebMvcTest 的组件扫描过滤器捕获,因为它不符合过滤器指定的任何类型。你可以通过在测试类上使用 @Import(MyConfiguration.class) 注解来显式地包含该配置。这将加载 MyConfiguration 中的所有 bean,包括在测试 Web 层时并不需要的 HikariDataSource bean。将配置类拆分为两个类将允许仅导入安全配置。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
return http.build();
}

}
java
import com.zaxxer.hikari.HikariDataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyDatasourceConfiguration {

@Bean
@ConfigurationProperties("app.datasource.second")
public HikariDataSource secondDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

}
java

当某个领域的 bean 需要包含在切片测试中时,使用单一的配置类可能会效率低下。相反,将应用程序的配置结构化为多个细粒度的类,每个类包含特定领域的 bean,可以仅在特定的切片测试中导入它们。