此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4spring-doc.cn

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4spring-doc.cn

Spring Boot 包括许多测试实用程序和支持类,以及一个提供常见测试依赖项的专用Starters。 本节回答有关测试的常见问题。spring-doc.cn

使用 Spring Security 进行测试

Spring Security 支持以特定用户身份运行测试。 例如,下面代码段中的测试将使用具有该角色的经过身份验证的用户运行。ADMINspring-doc.cn

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();
	}

}
import org.assertj.core.api.Assertions.assertThat
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

@WebMvcTest(UserController::class)
class MySecurityTests(@Autowired val mvc: MockMvcTester) {

	@Test
	@WithMockUser(roles = ["ADMIN"])
	fun requestProtectedUrlWithUser() {
		assertThat(mvc.get().uri("/"))
				.doesNotHaveFailed()
	}

}

Spring Security 提供了与 Spring MVC Test 的全面集成,这也可以在使用 slice 和 .@WebMvcTestMockMvcspring-doc.cn

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

用于包含在 Slice 测试中的结构类@Configuration

切片测试的工作原理是将 Spring Framework 的组件扫描限制为基于其类型的一组有限的组件。 对于不是通过组件扫描创建的任何 bean,例如,使用 Comments 创建的 bean,切片测试将无法在应用程序上下文中包含/排除它们。 请考虑以下示例:@Beanspring-doc.cn

import org.apache.commons.dbcp2.BasicDataSource;

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 BasicDataSource secondDataSource() {
		return DataSourceBuilder.create().type(BasicDataSource.class).build();
	}

}

对于具有上述类的应用程序,您可能希望在应用程序上下文中具有 Bean,以便您可以测试控制器端点是否得到正确保护。 但是,@WebMvcTest 的组件扫描筛选条件不会选取它,因为它与筛选条件指定的任何类型都不匹配。 您可以通过使用 . 这将加载所有 bean,包括 bean 中,这在测试 web 层时不是必需的。 将 configuration 类拆分为两个将允许仅导入 security configuration。@WebMvcTest@ConfigurationSecurityFilterChainMyConfiguration@Import(MyConfiguration.class)MyConfigurationBasicDataSourcespring-doc.cn

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();
	}

}
import org.apache.commons.dbcp2.BasicDataSource;

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 BasicDataSource secondDataSource() {
		return DataSourceBuilder.create().type(BasicDataSource.class).build();
	}

}

当需要将来自某个域的 bean 包含在 slice 测试中时,拥有单个配置类可能效率低下。 相反,将应用程序的配置构建为具有特定域的 bean 的多个细粒度类可以允许仅针对特定切片测试导入它们。spring-doc.cn