測試
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.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 的全面整合,這也可用於使用 @WebMvcTest
切片和 MockMvc
測試控制器時使用。
有關 Spring Security 測試支援的更多詳細資訊,請參閱 Spring Security 的參考文件。
為包含在切片測試中的 @Configuration
類進行結構設計
切片測試透過限制 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();
}
}
對於包含上述 @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();
}
}
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();
}
}
當需要將來自特定域的 Bean 包含在切片測試中時,擁有一個單獨的配置類可能會效率低下。相反,將應用的配置結構化為多個包含特定領域 Bean 的精細類,可以使得僅為特定的切片測試匯入它們。