测试

Spring Boot 包含多个测试工具和支持类,以及一个专门的起始程序,提供常见的测试依赖。 本节回答关于测试的常见问题。spring-doc.cadn.net.cn

使用Spring Security进行测试

Spring Security 支持以特定用户身份运行测试。 例如,下面摘要中的测试将使用一个经过认证且拥有管理角色。spring-doc.cadn.net.cn

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.webmvc.test.autoconfigure.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.webmvc.test.autoconfigure.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 测试的全面集成,这也可用于测试使用@WebMvcTest切片和莫克麦克.spring-doc.cadn.net.cn

有关 Spring Security 测试支持的更多细节,请参见 Spring Security 的参考文档spring-doc.cadn.net.cn

结构@Configuration切片测试中包含的类别

切片测试的工作原理是根据类型限制 Spring Framework 的组件扫描数量。 对于任何非通过组件扫描创建的豆子,例如,使用以下设备创建的豆子@Bean注释,切片测试无法将其纳入或排除应用上下文。 请考虑这个例子:spring-doc.cadn.net.cn

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) {
		http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
		return http.build();
	}

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

}

对于一个@WebMvcTest对于上述应用@Configuration你可能会期待拥有安全滤网链在应用上下文中使用 BEAN,这样你可以测试控制器端点是否安全。 然而MyConfiguration由于与@WebMvcTest的分量扫描Filter不匹配,因此无法检测到。 你可以通过在测试类中标注 显式包含配置@Import(MyConfiguration.class). 这样就能把所有豆子都装进去MyConfiguration包括光数据源BEAN测试网页版时并不需要。 将配置类拆分为两个,可以只导入安全配置。spring-doc.cadn.net.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) {
		http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
		return http.build();
	}

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

}

当需要包含某个域的豆子进入切片测试时,只有一个配置类效率会降低。 相反,将应用配置结构化为多个颗粒类,每个类别分别针对特定域的豆子,可以实现仅为特定切片测试导入这些类。spring-doc.cadn.net.cn