測試

Spring Boot 包含許多測試工具與支援類別,以及提供常用測試依賴的專用 starter。本節回答關於測試的常見問題。

使用 Spring Security 進行測試

Spring Security 提供以特定使用者身分執行測試的支援。例如,以下程式碼片段中的測試將以具有 ADMIN 角色的已驗證使用者身分執行。

  • Java

  • Kotlin

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.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

@WebMvcTest(UserController.class)
class MySecurityTests {

	@Autowired
	private MockMvc mvc;

	@Test
	@WithMockUser(roles = "ADMIN")
	void requestProtectedUrlWithUser() throws Exception {
		this.mvc.perform(get("/"));
	}

}
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.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders

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

	@Test
	@WithMockUser(roles = ["ADMIN"])
	fun requestProtectedUrlWithUser() {
		mvc.perform(MockMvcRequestBuilders.get("/"))
	}

}

Spring Security 提供與 Spring MVC Test 的全面整合,這也可以在測試使用 @WebMvcTest 切片和 MockMvc 的控制器時使用。

有關 Spring Security 測試支援的更多詳細資訊,請參閱 Spring Security 的參考文件

結構化 @Configuration 類別以包含在切片測試中

切片測試透過將 Spring Framework 的組件掃描限制為一組有限的組件(基於其類型)來運作。對於任何非透過組件掃描建立的 bean(例如,使用 @Bean 注解建立的 bean),切片測試將無法將它們包含/排除在應用程式上下文中。考慮以下範例

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

}

對於具有上述 @Configuration 類別的應用程式的 @WebMvcTest,您可能會期望在應用程式上下文中擁有 SecurityFilterChain bean,以便您可以測試您的控制器端點是否已正確保護。但是,MyConfiguration 不會被 @WebMvcTest 的組件掃描篩選器選取,因為它不符合篩選器指定的任何類型。您可以透過使用 @Import(MyConfiguration.class) 注解測試類別來明確包含組態。這將載入 MyConfiguration 中的所有 bean,包括在測試 Web 層時不需要的 BasicDataSource 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();
	}

}
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 需要包含在切片測試中時,擁有單一組態類別可能會效率低下。相反地,將應用程式的組態結構化為多個粒度類別(具有特定網域的 bean)可以使其僅針對特定切片測試匯入。