測試 Spring Boot 應用程式
Spring Boot 應用程式是 Spring ApplicationContext
,因此除了您通常對一般的 Spring context 執行的操作之外,不需要做任何非常特別的事情來測試它。
只有當您使用 SpringApplication 建立 context 時,Spring Boot 的外部屬性、記錄和其他功能才會預設安裝在 context 中。 |
Spring Boot 提供了 @SpringBootTest
註解,當您需要 Spring Boot 功能時,可以使用它來替代標準的 spring-test
@ContextConfiguration
註解。此註解透過SpringApplication
建立在您的測試中使用的 ApplicationContext
來運作。除了 @SpringBootTest
之外,還提供了一些其他的註解,用於測試應用程式更特定的切片。
如果您使用的是 JUnit 4,請不要忘記也將 @RunWith(SpringRunner.class) 新增到您的測試中,否則這些註解將被忽略。如果您使用的是 JUnit 5,則無需新增等效的 @ExtendWith(SpringExtension.class) ,因為 @SpringBootTest 和其他 @…Test 註解已經使用它進行了註解。 |
預設情況下,@SpringBootTest
不會啟動伺服器。您可以使用 @SpringBootTest
的 webEnvironment
屬性來進一步調整測試的執行方式
-
MOCK
(預設):載入網路ApplicationContext
並提供模擬網路環境。使用此註解時,不會啟動嵌入式伺服器。如果您的類別路徑上沒有可用的網路環境,則此模式會透明地回退到建立常規的非網路ApplicationContext
。它可以與@AutoConfigureMockMvc
或@AutoConfigureWebTestClient
結合使用,以進行基於模擬的網路應用程式測試。 -
RANDOM_PORT
:載入WebServerApplicationContext
並提供真實網路環境。嵌入式伺服器已啟動並在隨機埠上監聽。 -
DEFINED_PORT
:載入WebServerApplicationContext
並提供真實網路環境。嵌入式伺服器已啟動並在定義的埠 (來自您的application.properties
) 或預設埠8080
上監聽。 -
NONE
:使用SpringApplication
載入ApplicationContext
,但不提供任何網路環境 (模擬或其他)。
如果您的測試是 @Transactional ,則預設情況下,它會在每個測試方法結束時回滾交易。但是,由於將此配置與 RANDOM_PORT 或 DEFINED_PORT 結合使用會隱含地提供真實的 servlet 環境,因此 HTTP 客戶端和伺服器會在不同的執行緒中運行,因此也會在不同的交易中運行。在這種情況下,伺服器上啟動的任何交易都不會回滾。 |
如果您的應用程式針對管理伺服器使用不同的埠,則具有 webEnvironment = WebEnvironment.RANDOM_PORT 的 @SpringBootTest 也會在單獨的隨機埠上啟動管理伺服器。 |
偵測網路應用程式類型
如果 Spring MVC 可用,則會組態常規的基於 MVC 的應用程式 context。如果您只有 Spring WebFlux,我們將偵測到這一點,並組態基於 WebFlux 的應用程式 context。
如果兩者都存在,則 Spring MVC 優先。如果您想在這種情況下測試反應式網路應用程式,則必須設定 spring.main.web-application-type
屬性
-
Java
-
Kotlin
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(properties = "spring.main.web-application-type=reactive")
class MyWebFluxTests {
// ...
}
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest(properties = ["spring.main.web-application-type=reactive"])
class MyWebFluxTests {
// ...
}
偵測測試組態
如果您熟悉 Spring Test Framework,您可能習慣使用 @ContextConfiguration(classes=…)
以指定要載入哪個 Spring @Configuration
。或者,您可能經常在測試中使用巢狀 @Configuration
類別。
在測試 Spring Boot 應用程式時,通常不需要這樣做。只要您沒有明確定義主要組態,Spring Boot 的 @*Test
註解就會自動搜尋您的主要組態。
搜尋演算法會從包含測試的套件向上搜尋,直到找到使用 @SpringBootApplication
或 @SpringBootConfiguration
註解的類別為止。只要您以合理的方式結構化您的程式碼,通常就可以找到您的主要組態。
如果您使用測試註解來測試應用程式更特定的切片,則應避免在主方法的應用程式類別上新增特定於特定區域的組態設定。
|
如果您想自訂主要組態,可以使用巢狀 @TestConfiguration
類別。與將用於替代應用程式主要組態的巢狀 @Configuration
類別不同,巢狀 @TestConfiguration
類別會與應用程式的主要組態一起使用。
Spring 的測試框架會在測試之間快取應用程式 context。因此,只要您的測試共用相同的組態 (無論如何發現),載入 context 這個可能很耗時的程序就只會發生一次。 |
使用測試組態 Main 方法
通常,@SpringBootTest
發現的測試組態將是您的主要 @SpringBootApplication
。在大多數結構良好的應用程式中,此組態類別也將包含用於啟動應用程式的 main
方法。
例如,以下是典型 Spring Boot 應用程式的非常常見的程式碼模式
-
Java
-
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.docs.using.structuringyourcode.locatingthemainclass.MyApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
在上面的範例中,main
方法除了委派給 SpringApplication.run
之外,沒有做任何其他事情。但是,main
方法有可能更複雜,可以在呼叫 SpringApplication.run
之前套用自訂設定。
例如,以下是一個變更 banner 模式並設定其他設定檔的應用程式
-
Java
-
Kotlin
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.setAdditionalProfiles("myprofile");
application.run(args);
}
}
import org.springframework.boot.Banner
import org.springframework.boot.runApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args) {
setBannerMode(Banner.Mode.OFF)
setAdditionalProfiles("myprofile")
}
}
由於 main
方法中的自訂設定可能會影響產生的 ApplicationContext
,因此您也可能希望使用 main
方法來建立測試中使用的 ApplicationContext
。預設情況下,@SpringBootTest
不會呼叫您的 main
方法,而是直接使用類別本身來建立 ApplicationContext
如果您想變更此行為,可以將 @SpringBootTest
的 useMainMethod
屬性變更為 UseMainMethod.ALWAYS
或 UseMainMethod.WHEN_AVAILABLE
。當設定為 ALWAYS
時,如果找不到 main
方法,測試將會失敗。當設定為 WHEN_AVAILABLE
時,如果 main
方法可用,則會使用它,否則將使用標準載入機制。
例如,以下測試將會叫用 MyApplication
的 main
方法,以便建立 ApplicationContext
。如果 main 方法設定了其他設定檔,則這些設定檔將在 ApplicationContext
啟動時處於活動狀態。
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod;
@SpringBootTest(useMainMethod = UseMainMethod.ALWAYS)
class MyApplicationTests {
@Test
void exampleTest() {
// ...
}
}
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod
@SpringBootTest(useMainMethod = UseMainMethod.ALWAYS)
class MyApplicationTests {
@Test
fun exampleTest() {
// ...
}
}
排除測試組態
如果您的應用程式使用元件掃描 (例如,如果您使用 @SpringBootApplication
或 @ComponentScan
),您可能會發現僅為特定測試建立的頂層組態類別意外地在所有地方被選取。
正如我們先前所見,@TestConfiguration
可以用於測試的內部類別,以自訂主要組態。 @TestConfiguration
也可以用於頂層類別。這樣做表示不應透過掃描選取該類別。然後,您可以如以下範例所示,在需要它的地方明確匯入該類別
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
@SpringBootTest
@Import(MyTestsConfiguration.class)
class MyTests {
@Test
void exampleTest() {
// ...
}
}
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.Import
@SpringBootTest
@Import(MyTestsConfiguration::class)
class MyTests {
@Test
fun exampleTest() {
// ...
}
}
如果您直接使用 @ComponentScan (也就是說,不是透過 @SpringBootApplication ),則需要向其註冊 TypeExcludeFilter 。請參閱 TypeExcludeFilter API 文件以取得詳細資訊。 |
匯入的 @TestConfiguration 的處理時間早於內部類別 @TestConfiguration ,並且匯入的 @TestConfiguration 的處理時間將早於透過元件掃描找到的任何組態。一般來說,排序上的這種差異沒有明顯的影響,但如果您依賴 Bean 覆寫,則需要注意這一點。 |
使用應用程式引數
如果您的應用程式需要引數,您可以讓 @SpringBootTest
使用 args
屬性注入它們。
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.test.context.SpringBootTest;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(args = "--app.test=one")
class MyApplicationArgumentTests {
@Test
void applicationArgumentsPopulated(@Autowired ApplicationArguments args) {
assertThat(args.getOptionNames()).containsOnly("app.test");
assertThat(args.getOptionValues("app.test")).containsOnly("one");
}
}
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest(args = ["--app.test=one"])
class MyApplicationArgumentTests {
@Test
fun applicationArgumentsPopulated(@Autowired args: ApplicationArguments) {
assertThat(args.optionNames).containsOnly("app.test")
assertThat(args.getOptionValues("app.test")).containsOnly("one")
}
}
使用模擬環境進行測試
預設情況下,@SpringBootTest
不會啟動伺服器,而是設定模擬環境來測試網路端點。
使用 Spring MVC,我們可以使用 MockMvc
或 WebTestClient
查詢我們的網路端點,如以下範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class MyMockMvcTests {
@Test
void testWithMockMvc(@Autowired MockMvc mvc) throws Exception {
mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
}
// If Spring WebFlux is on the classpath, you can drive MVC tests with a WebTestClient
@Test
void testWithWebTestClient(@Autowired WebTestClient webClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Hello World");
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.test.web.reactive.server.expectBody
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
@SpringBootTest
@AutoConfigureMockMvc
class MyMockMvcTests {
@Test
fun testWithMockMvc(@Autowired mvc: MockMvc) {
mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.content().string("Hello World"))
}
// If Spring WebFlux is on the classpath, you can drive MVC tests with a WebTestClient
@Test
fun testWithWebTestClient(@Autowired webClient: WebTestClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Hello World")
}
}
如果您只想專注於網路層,而不啟動完整的 ApplicationContext ,請考慮改用 @WebMvcTest 。 |
使用 Spring WebFlux 端點,您可以使用 WebTestClient
,如以下範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
@SpringBootTest
@AutoConfigureWebTestClient
class MyMockWebTestClientTests {
@Test
void exampleTest(@Autowired WebTestClient webClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Hello World");
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.test.web.reactive.server.expectBody
@SpringBootTest
@AutoConfigureWebTestClient
class MyMockWebTestClientTests {
@Test
fun exampleTest(@Autowired webClient: WebTestClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Hello World")
}
}
在模擬環境中進行測試通常比在完整的 servlet 容器中執行更快。但是,由於模擬發生在 Spring MVC 層,因此依賴於較低層 servlet 容器行為的程式碼無法直接使用 MockMvc 進行測試。 例如,Spring Boot 的錯誤處理基於 servlet 容器提供的「錯誤頁面」支援。這表示,雖然您可以測試您的 MVC 層是否如預期拋出和處理例外狀況,但您無法直接測試是否呈現了特定的自訂錯誤頁面。如果您需要測試這些較低層次的考量,可以啟動完全運行的伺服器,如下節所述。 |
使用運行中的伺服器進行測試
如果您需要啟動完全運行的伺服器,我們建議您使用隨機埠。如果您使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
,則每次測試運行時都會隨機選擇一個可用的埠。
@LocalServerPort
註解可用於將實際使用的埠注入到您的測試中。為了方便起見,需要對啟動的伺服器進行 REST 呼叫的測試還可以自動裝配 WebTestClient
,它會將相對連結解析為正在運行的伺服器,並提供專用的 API 來驗證回應,如以下範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.web.reactive.server.WebTestClient;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortWebTestClientTests {
@Test
void exampleTest(@Autowired WebTestClient webClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Hello World");
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.test.web.reactive.server.expectBody
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortWebTestClientTests {
@Test
fun exampleTest(@Autowired webClient: WebTestClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Hello World")
}
}
WebTestClient 也可以與模擬環境一起使用,無需運行伺服器,只需使用 @AutoConfigureWebTestClient 註解您的測試類別即可。 |
此設定需要在類別路徑上使用 spring-webflux
。如果您無法或不願意新增 webflux,Spring Boot 也提供了 TestRestTemplate
功能
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortTestRestTemplateTests {
@Test
void exampleTest(@Autowired TestRestTemplate restTemplate) {
String body = restTemplate.getForObject("/", String.class);
assertThat(body).isEqualTo("Hello World");
}
}
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.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.client.TestRestTemplate
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortTestRestTemplateTests {
@Test
fun exampleTest(@Autowired restTemplate: TestRestTemplate) {
val body = restTemplate.getForObject("/", String::class.java)
assertThat(body).isEqualTo("Hello World")
}
}
自訂 WebTestClient
若要自訂 WebTestClient
Bean,請組態 WebTestClientBuilderCustomizer
Bean。任何此類 Bean 都會使用用於建立 WebTestClient
的 WebTestClient.Builder
呼叫。
使用 JMX
由於測試 context 框架會快取 context,因此預設情況下會停用 JMX,以防止相同的元件在相同的網域上註冊。如果此類測試需要存取 MBeanServer
,請考慮也將其標記為髒污
-
Java
-
Kotlin
import javax.management.MBeanServer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
class MyJmxTests {
@Autowired
private MBeanServer mBeanServer;
@Test
void exampleTest() {
assertThat(this.mBeanServer.getDomains()).contains("java.lang");
// ...
}
}
import javax.management.MBeanServer
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.context.SpringBootTest
import org.springframework.test.annotation.DirtiesContext
@SpringBootTest(properties = ["spring.jmx.enabled=true"])
@DirtiesContext
class MyJmxTests(@Autowired val mBeanServer: MBeanServer) {
@Test
fun exampleTest() {
assertThat(mBeanServer.domains).contains("java.lang")
// ...
}
}
使用 Observability
如果您使用 @AutoConfigureObservability
註解切片測試,它會自動組態 ObservationRegistry
。
使用指標
無論您的類別路徑如何,當使用 @SpringBootTest
時,除了記憶體支援的儀表登錄檔之外,儀表登錄檔都不會自動組態。
如果您需要在整合測試中將指標匯出到不同的後端,請使用 @AutoConfigureObservability
註解它。
如果您使用 @AutoConfigureObservability
註解切片測試,它會自動組態記憶體中的 MeterRegistry
。切片測試中的資料匯出不受 @AutoConfigureObservability
註解支援。
使用追蹤
無論您的類別路徑如何,當使用 @SpringBootTest
時,都不會自動組態報告資料的追蹤元件。
如果您需要在整合測試中使用這些元件,請使用 @AutoConfigureObservability
註解測試。
如果您建立了您自己的報告元件 (例如,自訂 SpanExporter
或 SpanHandler
),並且您不希望它們在測試中處於活動狀態,則可以使用 @ConditionalOnEnabledTracing
註解來停用它們。
如果您使用 @AutoConfigureObservability
註解切片測試,它會自動組態 no-op Tracer
。切片測試中的資料匯出不受 @AutoConfigureObservability
註解支援。
模擬和間諜 Bean
在運行測試時,有時需要模擬應用程式 context 中的某些元件。例如,您可能在某些遠端服務上具有 facade,而這些服務在開發期間不可用。當您想要模擬在真實環境中可能難以觸發的失敗時,模擬也很有用。
Spring Boot 包含 @MockBean
註解,可用於在您的 ApplicationContext
內部為 Bean 定義 Mockito 模擬。您可以使用此註解來新增 Bean 或取代單個現有的 Bean 定義。此註解可以直接在測試類別、測試中的欄位或 @Configuration
類別和欄位上使用。在欄位上使用時,也會注入已建立模擬的實例。模擬 Bean 會在每個測試方法之後自動重設。
如果您的測試使用 Spring Boot 的測試註解之一 (例如
|
以下範例使用模擬實作取代現有的 RemoteService
Bean
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
@SpringBootTest
class MyTests {
@Autowired
private Reverser reverser;
@MockBean
private RemoteService remoteService;
@Test
void exampleTest() {
given(this.remoteService.getValue()).willReturn("spring");
String reverse = this.reverser.getReverseValue(); // Calls injected RemoteService
assertThat(reverse).isEqualTo("gnirps");
}
}
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
@SpringBootTest
class MyTests(@Autowired val reverser: Reverser, @MockBean val remoteService: RemoteService) {
@Test
fun exampleTest() {
given(remoteService.value).willReturn("spring")
val reverse = reverser.reverseValue // Calls injected RemoteService
assertThat(reverse).isEqualTo("gnirps")
}
}
@MockBean 無法用於模擬在應用程式 context 重新整理期間執行的 Bean 的行為。當執行測試時,應用程式 context 重新整理已完成,並且組態模擬行為為時已晚。我們建議在此情況下使用 @Bean 方法來建立和組態模擬。 |
此外,您可以使用 @SpyBean
將任何現有的 Bean 與 Mockito spy
包裝在一起。請參閱 SpyBean
API 文件以取得完整詳細資訊。
雖然 Spring 的測試框架會在測試之間快取應用程式 context,並為共用相同組態的測試重複使用 context,但使用 @MockBean 或 @SpyBean 會影響快取索引鍵,這很可能會增加 context 的數量。 |
如果您使用 @SpyBean 來監視具有 @Cacheable 方法 (這些方法依名稱引用參數) 的 Bean,則必須使用 -parameters 編譯您的應用程式。這可確保一旦 Bean 被監視,參數名稱即可用於快取基礎架構。 |
當您使用 @SpyBean 來監視由 Spring 代理的 Bean 時,在某些情況下您可能需要移除 Spring 的代理,例如在使用 given 或 when 設定預期時。使用 AopTestUtils.getTargetObject(yourProxiedSpy) 來執行此操作。 |
自動組態測試
Spring Boot 的自動組態系統適用於應用程式,但有時對測試來說有點過多。通常,僅載入測試應用程式「切片」所需的部分組態會有所幫助。例如,您可能想要測試 Spring MVC 控制器是否正確對應 URL,並且您不希望在這些測試中涉及資料庫呼叫,或者您可能想要測試 JPA 實體,並且在這些測試運行時您對網路層不感興趣。
spring-boot-test-autoconfigure
模組包含許多註解,可用於自動組態此類「切片」。它們中的每一個都以類似的方式運作,提供載入 ApplicationContext
的 @…Test
註解,以及可用於自訂自動組態設定的一個或多個 @AutoConfigure…
註解。
每個切片都將元件掃描限制為適當的元件,並載入非常受限的自動組態類別集。如果您需要排除其中一個,大多數 @…Test 註解都提供 excludeAutoConfiguration 屬性。或者,您可以使用 @ImportAutoConfiguration#exclude 。 |
不支援在一個測試中使用多個 @…Test 註解來包含多個「切片」。如果您需要多個「切片」,請選擇其中一個 @…Test 註解,並手動包含其他「切片」的 @AutoConfigure… 註解。 |
也可以將 @AutoConfigure… 註解與標準 @SpringBootTest 註解一起使用。如果您對「切片」您的應用程式不感興趣,但想要一些自動組態的測試 Bean,則可以使用此組合。 |
自動組態 JSON 測試
若要測試物件 JSON 序列化和反序列化是否按預期運作,您可以使用 @JsonTest
註解。 @JsonTest
自動組態可用的受支援 JSON 對應器,它可以是以下程式庫之一
-
Jackson
ObjectMapper
、任何@JsonComponent
Bean 和任何 JacksonModule
-
Gson
-
Jsonb
@JsonTest 啟用的自動組態清單可以在附錄中找到。 |
如果您需要組態自動組態的元素,可以使用 @AutoConfigureJsonTesters
註解。
Spring Boot 包含基於 AssertJ 的輔助程式,這些輔助程式與 JSONAssert 和 JsonPath 程式庫一起使用,以檢查 JSON 是否如預期顯示。 JacksonTester
、GsonTester
、JsonbTester
和 BasicJsonTester
類別分別可用於 Jackson、Gson、Jsonb 和字串。當使用 @JsonTest
時,測試類別上的任何輔助欄位都可以 @Autowired
。以下範例顯示 Jackson 的測試類別
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.json.JacksonTester;
import static org.assertj.core.api.Assertions.assertThat;
@JsonTest
class MyJsonTests {
@Autowired
private JacksonTester<VehicleDetails> json;
@Test
void serialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make").isEqualTo("Honda");
}
@Test
void deserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content)).isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}
}
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.json.JsonTest
import org.springframework.boot.test.json.JacksonTester
@JsonTest
class MyJsonTests(@Autowired val json: JacksonTester<VehicleDetails>) {
@Test
fun serialize() {
val details = VehicleDetails("Honda", "Civic")
// Assert against a `.json` file in the same package as the test
assertThat(json.write(details)).isEqualToJson("expected.json")
// Or use JSON path based assertions
assertThat(json.write(details)).hasJsonPathStringValue("@.make")
assertThat(json.write(details)).extractingJsonPathStringValue("@.make").isEqualTo("Honda")
}
@Test
fun deserialize() {
val content = "{\"make\":\"Ford\",\"model\":\"Focus\"}"
assertThat(json.parse(content)).isEqualTo(VehicleDetails("Ford", "Focus"))
assertThat(json.parseObject(content).make).isEqualTo("Ford")
}
}
JSON 輔助類別也可以直接在標準單元測試中使用。若要執行此操作,如果您不使用 @JsonTest ,請在 @Before 方法中呼叫輔助程式的 initFields 方法。 |
如果您使用 Spring Boot 基於 AssertJ 的輔助程式來斷言給定 JSON 路徑上的數字值,則您可能無法根據類型使用 isEqualTo
。相反,您可以使用 AssertJ 的 satisfies
來斷言該值是否符合給定的條件。例如,以下範例斷言實際數字是接近 0.15
的浮點值,偏移量在 0.01
範圍內。
-
Java
-
Kotlin
@Test
void someTest() throws Exception {
SomeObject value = new SomeObject(0.152f);
assertThat(this.json.write(value)).extractingJsonPathNumberValue("@.test.numberValue")
.satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));
}
@Test
fun someTest() {
val value = SomeObject(0.152f)
assertThat(json.write(value)).extractingJsonPathNumberValue("@.test.numberValue")
.satisfies(ThrowingConsumer { number ->
assertThat(number.toFloat()).isCloseTo(0.15f, within(0.01f))
})
}
自動組態 Spring MVC 測試
若要測試 Spring MVC 控制器是否按預期運作,請使用 @WebMvcTest
註解。 @WebMvcTest
自動組態 Spring MVC 基礎架構,並將掃描的 Bean 限制為 @Controller
、@ControllerAdvice
、@JsonComponent
、Converter
、GenericConverter
、Filter
、HandlerInterceptor
、WebMvcConfigurer
、WebMvcRegistrations
和 HandlerMethodArgumentResolver
。當使用 @WebMvcTest
註解時,不會掃描常規的 @Component
和 @ConfigurationProperties
Bean。 @EnableConfigurationProperties
可用於包含 @ConfigurationProperties
Bean。
@WebMvcTest 啟用的自動組態設定清單可以在附錄中找到。 |
如果您需要註冊額外的元件,例如 Jackson Module ,您可以使用測試中的 @Import 匯入其他組態類別。 |
通常,@WebMvcTest
僅限於單個控制器,並與 @MockBean
結合使用,以為所需的協作者提供模擬實作。
@WebMvcTest
也會自動組態 MockMvc
。 Mock MVC 提供了一種強大的方法,可以快速測試 MVC 控制器,而無需啟動完整的 HTTP 伺服器。
您也可以在非 @WebMvcTest (例如 @SpringBootTest ) 中自動組態 MockMvc ,方法是使用 @AutoConfigureMockMvc 註解它。以下範例使用 MockMvc |
-
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.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(UserVehicleController.class)
class MyControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private UserVehicleService userVehicleService;
@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
}
}
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
@WebMvcTest(UserVehicleController::class)
class MyControllerTests(@Autowired val mvc: MockMvc) {
@MockBean
lateinit var userVehicleService: UserVehicleService
@Test
fun testExample() {
given(userVehicleService.getVehicleDetails("sboot"))
.willReturn(VehicleDetails("Honda", "Civic"))
mvc.perform(MockMvcRequestBuilders.get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.content().string("Honda Civic"))
}
}
如果您需要組態自動組態的元素 (例如,何時應套用 servlet 篩選器),則可以使用 @AutoConfigureMockMvc 註解中的屬性。 |
如果您使用 HtmlUnit 和 Selenium,自動組態也會提供 HtmlUnit WebClient
Bean 和/或 Selenium WebDriver
Bean。以下範例使用 HtmlUnit
-
Java
-
Kotlin
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
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.boot.test.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
@WebMvcTest(UserVehicleController.class)
class MyHtmlUnitTests {
@Autowired
private WebClient webClient;
@MockBean
private UserVehicleService userVehicleService;
@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
}
}
import com.gargoylesoftware.htmlunit.WebClient
import com.gargoylesoftware.htmlunit.html.HtmlPage
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
@WebMvcTest(UserVehicleController::class)
class MyHtmlUnitTests(@Autowired val webClient: WebClient) {
@MockBean
lateinit var userVehicleService: UserVehicleService
@Test
fun testExample() {
given(userVehicleService.getVehicleDetails("sboot")).willReturn(VehicleDetails("Honda", "Civic"))
val page = webClient.getPage<HtmlPage>("/sboot/vehicle.html")
assertThat(page.body.textContent).isEqualTo("Honda Civic")
}
}
預設情況下,Spring Boot 會將 WebDriver Bean 放在特殊的「範圍」中,以確保驅動程式在每次測試後退出,並注入新的實例。如果您不想要此行為,可以將 @Scope("singleton") 新增到您的 WebDriver @Bean 定義中。 |
由 Spring Boot 建立的 webDriver scope 將會取代任何使用者定義的同名 scope。如果您定義了自己的 webDriver scope,您可能會發現當您使用 @WebMvcTest 時它會停止運作。 |
如果您的 classpath 中有 Spring Security,@WebMvcTest
也會掃描 WebSecurityConfigurer
beans。您可以改用 Spring Security 的測試支援,而不是完全停用此類測試的安全性。關於如何使用 Spring Security 的 MockMvc
支援的更多詳細資訊,可以在「操作指南」章節的使用 Spring Security 進行測試中找到。
有時編寫 Spring MVC 測試可能還不夠;Spring Boot 可以幫助您執行使用實際伺服器的完整端對端測試。 |
自動配置 Spring WebFlux 測試
為了測試 Spring WebFlux controllers 是否如預期般運作,您可以使用 @WebFluxTest
註解。@WebFluxTest
自動配置 Spring WebFlux 基礎架構,並將掃描的 beans 限制為 @Controller
、@ControllerAdvice
、@JsonComponent
、Converter
、GenericConverter
、WebFilter
和 WebFluxConfigurer
。當使用 @WebFluxTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @WebFluxTest 啟用的自動配置列表,可以在附錄中找到。 |
如果您需要註冊額外的組件,例如 Jackson Module ,您可以使用測試中的 @Import 匯入額外的配置類別。 |
通常,@WebFluxTest
僅限於單一 controller,並與 @MockBean
註解結合使用,以為所需的協作者提供模擬實作。
@WebFluxTest
還自動配置了 WebTestClient
,它提供了一種強大的方法來快速測試 WebFlux controllers,而無需啟動完整的 HTTP 伺服器。
您也可以在非 @WebFluxTest 的環境(例如 @SpringBootTest )中自動配置 WebTestClient ,方法是使用 @AutoConfigureWebTestClient 註解它。以下範例顯示了一個同時使用 @WebFluxTest 和 WebTestClient 的類別 |
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.mockito.BDDMockito.given;
@WebFluxTest(UserVehicleController.class)
class MyControllerTests {
@Autowired
private WebTestClient webClient;
@MockBean
private UserVehicleService userVehicleService;
@Test
void testExample() {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN).exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Honda Civic");
}
}
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.http.MediaType
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.test.web.reactive.server.expectBody
@WebFluxTest(UserVehicleController::class)
class MyControllerTests(@Autowired val webClient: WebTestClient) {
@MockBean
lateinit var userVehicleService: UserVehicleService
@Test
fun testExample() {
given(userVehicleService.getVehicleDetails("sboot"))
.willReturn(VehicleDetails("Honda", "Civic"))
webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN).exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Honda Civic")
}
}
此設定僅受 WebFlux 應用程式支援,因為在模擬的 Web 應用程式中使用 WebTestClient 目前僅適用於 WebFlux。 |
@WebFluxTest 無法偵測透過 functional web framework 註冊的路由。為了在上下文中測試 RouterFunction beans,請考慮使用 @Import 自行匯入您的 RouterFunction ,或使用 @SpringBootTest 。 |
@WebFluxTest 無法偵測註冊為 SecurityWebFilterChain 類型的 @Bean 的自訂安全性配置。為了將其包含在您的測試中,您需要使用 @Import 或使用 @SpringBootTest 匯入註冊該 bean 的配置。 |
有時編寫 Spring WebFlux 測試可能還不夠;Spring Boot 可以幫助您執行使用實際伺服器的完整端對端測試。 |
自動配置 Spring GraphQL 測試
Spring GraphQL 提供了一個專用的測試支援模組;您需要將其新增到您的專案中
<dependencies>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Unless already present in the compile scope -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
dependencies {
testImplementation("org.springframework.graphql:spring-graphql-test")
// Unless already present in the implementation configuration
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
}
此測試模組隨附了 GraphQlTester。tester 在測試中被大量使用,因此請務必熟悉其使用方式。有 GraphQlTester
的變體,Spring Boot 將根據測試類型自動配置它們
-
ExecutionGraphQlServiceTester
在伺服器端執行測試,無需用戶端或傳輸 -
HttpGraphQlTester
使用連接到伺服器的用戶端執行測試,無論有無即時伺服器
Spring Boot 幫助您使用 @GraphQlTest
註解來測試您的 Spring GraphQL Controllers。@GraphQlTest
自動配置 Spring GraphQL 基礎架構,不涉及任何傳輸或伺服器。這將掃描的 beans 限制為 @Controller
、RuntimeWiringConfigurer
、JsonComponent
、Converter
、GenericConverter
、DataFetcherExceptionResolver
、Instrumentation
和 GraphQlSourceBuilderCustomizer
。當使用 @GraphQlTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @GraphQlTest 啟用的自動配置列表,可以在附錄中找到。 |
通常,@GraphQlTest
僅限於一組 controllers,並與 @MockBean
註解結合使用,以為所需的協作者提供模擬實作。
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.docs.web.graphql.runtimewiring.GreetingController;
import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest;
import org.springframework.graphql.test.tester.GraphQlTester;
@GraphQlTest(GreetingController.class)
class GreetingControllerTests {
@Autowired
private GraphQlTester graphQlTester;
@Test
void shouldGreetWithSpecificName() {
this.graphQlTester.document("{ greeting(name: \"Alice\") } ")
.execute()
.path("greeting")
.entity(String.class)
.isEqualTo("Hello, Alice!");
}
@Test
void shouldGreetWithDefaultName() {
this.graphQlTester.document("{ greeting } ")
.execute()
.path("greeting")
.entity(String.class)
.isEqualTo("Hello, Spring!");
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.docs.web.graphql.runtimewiring.GreetingController
import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest
import org.springframework.graphql.test.tester.GraphQlTester
@GraphQlTest(GreetingController::class)
internal class GreetingControllerTests {
@Autowired
lateinit var graphQlTester: GraphQlTester
@Test
fun shouldGreetWithSpecificName() {
graphQlTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String::class.java)
.isEqualTo("Hello, Alice!")
}
@Test
fun shouldGreetWithDefaultName() {
graphQlTester.document("{ greeting } ").execute().path("greeting").entity(String::class.java)
.isEqualTo("Hello, Spring!")
}
}
@SpringBootTest
測試是完整的整合測試,涉及整個應用程式。當使用隨機或定義的埠時,會配置即時伺服器,並且會自動貢獻 HttpGraphQlTester
bean,以便您可以使用它來測試您的伺服器。當配置 MOCK 環境時,您也可以透過使用 @AutoConfigureHttpGraphQlTester
註解您的測試類別來請求 HttpGraphQlTester
bean
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
@AutoConfigureHttpGraphQlTester
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class GraphQlIntegrationTests {
@Test
void shouldGreetWithSpecificName(@Autowired HttpGraphQlTester graphQlTester) {
HttpGraphQlTester authenticatedTester = graphQlTester.mutate()
.webTestClient((client) -> client.defaultHeaders((headers) -> headers.setBasicAuth("admin", "ilovespring")))
.build();
authenticatedTester.document("{ greeting(name: \"Alice\") } ")
.execute()
.path("greeting")
.entity(String.class)
.isEqualTo("Hello, Alice!");
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.graphql.test.tester.HttpGraphQlTester
import org.springframework.http.HttpHeaders
import org.springframework.test.web.reactive.server.WebTestClient
@AutoConfigureHttpGraphQlTester
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class GraphQlIntegrationTests {
@Test
fun shouldGreetWithSpecificName(@Autowired graphQlTester: HttpGraphQlTester) {
val authenticatedTester = graphQlTester.mutate()
.webTestClient { client: WebTestClient.Builder ->
client.defaultHeaders { headers: HttpHeaders ->
headers.setBasicAuth("admin", "ilovespring")
}
}.build()
authenticatedTester.document("{ greeting(name: \"Alice\") } ").execute()
.path("greeting").entity(String::class.java).isEqualTo("Hello, Alice!")
}
}
自動配置 Data Cassandra 測試
您可以使用 @DataCassandraTest
來測試 Cassandra 應用程式。預設情況下,它會配置 CassandraTemplate
,掃描 @Table
類別,並配置 Spring Data Cassandra 儲存庫。當使用 @DataCassandraTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 Cassandra 與 Spring Boot 一起使用的更多資訊,請參閱Cassandra。)
關於 @DataCassandraTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了在 Spring Boot 中使用 Cassandra 測試的典型設定
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest;
@DataCassandraTest
class MyDataCassandraTests {
@Autowired
private SomeRepository repository;
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest
@DataCassandraTest
class MyDataCassandraTests(@Autowired val repository: SomeRepository)
自動配置 Data Couchbase 測試
您可以使用 @DataCouchbaseTest
來測試 Couchbase 應用程式。預設情況下,它會配置 CouchbaseTemplate
或 ReactiveCouchbaseTemplate
,掃描 @Document
類別,並配置 Spring Data Couchbase 儲存庫。當使用 @DataCouchbaseTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 Couchbase 與 Spring Boot 一起使用的更多資訊,請參閱本章稍早的Couchbase。)
關於 @DataCouchbaseTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了在 Spring Boot 中使用 Couchbase 測試的典型設定
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.couchbase.DataCouchbaseTest;
@DataCouchbaseTest
class MyDataCouchbaseTests {
@Autowired
private SomeRepository repository;
// ...
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.couchbase.DataCouchbaseTest
@DataCouchbaseTest
class MyDataCouchbaseTests(@Autowired val repository: SomeRepository) {
// ...
}
自動配置 Data Elasticsearch 測試
您可以使用 @DataElasticsearchTest
來測試 Elasticsearch 應用程式。預設情況下,它會配置 ElasticsearchRestTemplate
,掃描 @Document
類別,並配置 Spring Data Elasticsearch 儲存庫。當使用 @DataElasticsearchTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 Elasticsearch 與 Spring Boot 一起使用的更多資訊,請參閱本章稍早的Elasticsearch。)
關於 @DataElasticsearchTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了在 Spring Boot 中使用 Elasticsearch 測試的典型設定
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.elasticsearch.DataElasticsearchTest;
@DataElasticsearchTest
class MyDataElasticsearchTests {
@Autowired
private SomeRepository repository;
// ...
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.elasticsearch.DataElasticsearchTest
@DataElasticsearchTest
class MyDataElasticsearchTests(@Autowired val repository: SomeRepository) {
// ...
}
自動配置 Data JPA 測試
您可以使用 @DataJpaTest
註解來測試 JPA 應用程式。預設情況下,它會掃描 @Entity
類別並配置 Spring Data JPA 儲存庫。如果 classpath 上有可用的嵌入式資料庫,它也會配置一個。SQL 查詢預設會透過將 spring.jpa.show-sql
屬性設定為 true
來記錄。可以使用註解的 showSql
屬性來停用此功能。
當使用 @DataJpaTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @DataJpaTest 啟用的自動配置設定列表,可以在附錄中找到。 |
預設情況下,data JPA 測試是事務性的,並且在每個測試結束時回滾。有關更多詳細資訊,請參閱 Spring Framework 參考文件中的相關章節。如果那不是您想要的,您可以如下所示為測試或整個類別停用事務管理
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyNonTransactionalTests {
// ...
}
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyNonTransactionalTests {
// ...
}
Data JPA 測試也可以注入 TestEntityManager
bean,它提供了標準 JPA EntityManager
的替代方案,專門為測試而設計。
TestEntityManager 也可以透過新增 @AutoConfigureTestEntityManager 自動配置到您的任何基於 Spring 的測試類別。 這樣做時,請確保您的測試在事務中運行,例如在您的測試類別或方法上新增 @Transactional 。 |
如果您需要,JdbcTemplate
也可用。以下範例顯示了 @DataJpaTest
註解的使用
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
class MyRepositoryTests {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository repository;
@Test
void testExample() {
this.entityManager.persist(new User("sboot", "1234"));
User user = this.repository.findByUsername("sboot");
assertThat(user.getUsername()).isEqualTo("sboot");
assertThat(user.getEmployeeNumber()).isEqualTo("1234");
}
}
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.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
@DataJpaTest
class MyRepositoryTests(@Autowired val entityManager: TestEntityManager, @Autowired val repository: UserRepository) {
@Test
fun testExample() {
entityManager.persist(User("sboot", "1234"))
val user = repository.findByUsername("sboot")
assertThat(user?.username).isEqualTo("sboot")
assertThat(user?.employeeNumber).isEqualTo("1234")
}
}
記憶體中的嵌入式資料庫通常適用於測試,因為它們速度很快且不需要任何安裝。但是,如果您希望針對真實資料庫執行測試,則可以使用 @AutoConfigureTestDatabase
註解,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class MyRepositoryTests {
// ...
}
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class MyRepositoryTests {
// ...
}
自動配置 JDBC 測試
@JdbcTest
類似於 @DataJpaTest
,但適用於僅需要 DataSource
且不使用 Spring Data JDBC 的測試。預設情況下,它會配置記憶體中的嵌入式資料庫和 JdbcTemplate
。當使用 @JdbcTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @JdbcTest 啟用的自動配置列表,可以在附錄中找到。 |
預設情況下,JDBC 測試是事務性的,並且在每個測試結束時回滾。有關更多詳細資訊,請參閱 Spring Framework 參考文件中的相關章節。如果那不是您想要的,您可以如下所示為測試或整個類別停用事務管理
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyTransactionalTests {
}
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyTransactionalTests
如果您希望您的測試針對真實資料庫運行,則可以使用 @AutoConfigureTestDatabase
註解,方式與 @DataJpaTest
相同。(請參閱自動配置 Data JPA 測試。)
自動配置 Data JDBC 測試
@DataJdbcTest
類似於 @JdbcTest
,但適用於使用 Spring Data JDBC 儲存庫的測試。預設情況下,它會配置記憶體中的嵌入式資料庫、JdbcTemplate
和 Spring Data JDBC 儲存庫。當使用 @DataJdbcTest
註解時,僅掃描 AbstractJdbcConfiguration
子類別,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @DataJdbcTest 啟用的自動配置列表,可以在附錄中找到。 |
預設情況下,Data JDBC 測試是事務性的,並且在每個測試結束時回滾。有關更多詳細資訊,請參閱 Spring Framework 參考文件中的相關章節。如果那不是您想要的,您可以為測試或整個測試類別停用事務管理,如JDBC 範例中所示。
如果您希望您的測試針對真實資料庫運行,則可以使用 @AutoConfigureTestDatabase
註解,方式與 @DataJpaTest
相同。(請參閱自動配置 Data JPA 測試。)
自動配置 Data R2DBC 測試
@DataR2dbcTest
類似於 @DataJdbcTest
,但適用於使用 Spring Data R2DBC 儲存庫的測試。預設情況下,它會配置記憶體中的嵌入式資料庫、R2dbcEntityTemplate
和 Spring Data R2DBC 儲存庫。當使用 @DataR2dbcTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @DataR2dbcTest 啟用的自動配置列表,可以在附錄中找到。 |
預設情況下,Data R2DBC 測試不是事務性的。
如果您希望您的測試針對真實資料庫運行,則可以使用 @AutoConfigureTestDatabase
註解,方式與 @DataJpaTest
相同。(請參閱自動配置 Data JPA 測試。)
自動配置 jOOQ 測試
您可以像 @JdbcTest
一樣使用 @JooqTest
,但適用於 jOOQ 相關的測試。由於 jOOQ 非常依賴與資料庫 schema 對應的基於 Java 的 schema,因此會使用現有的 DataSource
。如果您想用記憶體資料庫替換它,可以使用 @AutoConfigureTestDatabase
來覆寫這些設定。(有關將 jOOQ 與 Spring Boot 一起使用的更多資訊,請參閱使用 jOOQ。)當使用 @JooqTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @JooqTest 啟用的自動配置列表,可以在附錄中找到。 |
@JooqTest
配置了 DSLContext
。以下範例顯示了 @JooqTest
註解的使用
-
Java
-
Kotlin
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jooq.JooqTest;
@JooqTest
class MyJooqTests {
@Autowired
private DSLContext dslContext;
// ...
}
import org.jooq.DSLContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jooq.JooqTest
@JooqTest
class MyJooqTests(@Autowired val dslContext: DSLContext) {
// ...
}
JOOQ 測試預設是事務性的,並且在每個測試結束時回滾。如果那不是您想要的,您可以為測試或整個測試類別停用事務管理,如JDBC 範例中所示。
自動配置 Data MongoDB 測試
您可以使用 @DataMongoTest
來測試 MongoDB 應用程式。預設情況下,它會配置 MongoTemplate
,掃描 @Document
類別,並配置 Spring Data MongoDB 儲存庫。當使用 @DataMongoTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 MongoDB 與 Spring Boot 一起使用的更多資訊,請參閱MongoDB。)
關於 @DataMongoTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下類別顯示了 @DataMongoTest
註解的使用
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoTemplate;
@DataMongoTest
class MyDataMongoDbTests {
@Autowired
private MongoTemplate mongoTemplate;
// ...
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest
import org.springframework.data.mongodb.core.MongoTemplate
@DataMongoTest
class MyDataMongoDbTests(@Autowired val mongoTemplate: MongoTemplate) {
// ...
}
自動配置 Data Neo4j 測試
您可以使用 @DataNeo4jTest
來測試 Neo4j 應用程式。預設情況下,它會掃描 @Node
類別,並配置 Spring Data Neo4j 儲存庫。當使用 @DataNeo4jTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 Neo4J 與 Spring Boot 一起使用的更多資訊,請參閱Neo4j。)
關於 @DataNeo4jTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了在 Spring Boot 中使用 Neo4J 測試的典型設定
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
@DataNeo4jTest
class MyDataNeo4jTests {
@Autowired
private SomeRepository repository;
// ...
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest
@DataNeo4jTest
class MyDataNeo4jTests(@Autowired val repository: SomeRepository) {
// ...
}
預設情況下,Data Neo4j 測試是事務性的,並且在每個測試結束時回滾。有關更多詳細資訊,請參閱 Spring Framework 參考文件中的相關章節。如果那不是您想要的,您可以如下所示為測試或整個類別停用事務管理
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyDataNeo4jTests {
}
import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
@DataNeo4jTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyDataNeo4jTests
反應式存取不支援事務性測試。如果您正在使用這種風格,則必須如上所述配置 @DataNeo4jTest 測試。 |
自動配置 Data Redis 測試
您可以使用 @DataRedisTest
來測試 Redis 應用程式。預設情況下,它會掃描 @RedisHash
類別並配置 Spring Data Redis 儲存庫。當使用 @DataRedisTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 Redis 與 Spring Boot 一起使用的更多資訊,請參閱Redis。)
關於 @DataRedisTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了 @DataRedisTest
註解的使用
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest;
@DataRedisTest
class MyDataRedisTests {
@Autowired
private SomeRepository repository;
// ...
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.redis.DataRedisTest
@DataRedisTest
class MyDataRedisTests(@Autowired val repository: SomeRepository) {
// ...
}
自動配置 Data LDAP 測試
您可以使用 @DataLdapTest
來測試 LDAP 應用程式。預設情況下,它會配置記憶體中的嵌入式 LDAP(如果可用)、配置 LdapTemplate
、掃描 @Entry
類別,並配置 Spring Data LDAP 儲存庫。當使用 @DataLdapTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。(有關將 LDAP 與 Spring Boot 一起使用的更多資訊,請參閱LDAP。)
關於 @DataLdapTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了 @DataLdapTest
註解的使用
-
Java
-
Kotlin
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
import org.springframework.ldap.core.LdapTemplate;
@DataLdapTest
class MyDataLdapTests {
@Autowired
private LdapTemplate ldapTemplate;
// ...
}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest
import org.springframework.ldap.core.LdapTemplate
@DataLdapTest
class MyDataLdapTests(@Autowired val ldapTemplate: LdapTemplate) {
// ...
}
記憶體中的嵌入式 LDAP 通常適用於測試,因為它速度很快且不需要任何開發人員安裝。但是,如果您希望針對真實 LDAP 伺服器執行測試,則應排除嵌入式 LDAP 自動配置,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest;
@DataLdapTest(excludeAutoConfiguration = EmbeddedLdapAutoConfiguration.class)
class MyDataLdapTests {
// ...
}
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration
import org.springframework.boot.test.autoconfigure.data.ldap.DataLdapTest
@DataLdapTest(excludeAutoConfiguration = [EmbeddedLdapAutoConfiguration::class])
class MyDataLdapTests {
// ...
}
自動配置 REST Clients
您可以使用 @RestClientTest
註解來測試 REST clients。預設情況下,它會自動配置 Jackson、GSON 和 Jsonb 支援,配置 RestTemplateBuilder
和 RestClient.Builder
,並新增對 MockRestServiceServer
的支援。當使用 @RestClientTest
註解時,常規的 @Component
和 @ConfigurationProperties
beans 不會被掃描。可以使用 @EnableConfigurationProperties
來包含 @ConfigurationProperties
beans。
關於 @RestClientTest 啟用的自動配置設定列表,可以在附錄中找到。 |
您要測試的特定 beans 應透過使用 @RestClientTest
的 value
或 components
屬性來指定。
當在測試中的 beans 中使用 RestTemplateBuilder
,並且在建構 RestTemplate
時已呼叫 RestTemplateBuilder.rootUri(String rootUri)
,則應從 MockRestServiceServer
期望中省略根 URI,如下列範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.client.MockRestServiceServer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
@RestClientTest(org.springframework.boot.docs.testing.springbootapplications.autoconfiguredrestclient.RemoteVehicleDetailsService.class)
class MyRestTemplateServiceTests {
@Autowired
private RemoteVehicleDetailsService service;
@Autowired
private MockRestServiceServer server;
@Test
void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() {
this.server.expect(requestTo("/greet/details")).andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
String greeting = this.service.callRestService();
assertThat(greeting).isEqualTo("hello");
}
}
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.client.RestClientTest
import org.springframework.http.MediaType
import org.springframework.test.web.client.MockRestServiceServer
import org.springframework.test.web.client.match.MockRestRequestMatchers
import org.springframework.test.web.client.response.MockRestResponseCreators
@RestClientTest(RemoteVehicleDetailsService::class)
class MyRestTemplateServiceTests(
@Autowired val service: RemoteVehicleDetailsService,
@Autowired val server: MockRestServiceServer) {
@Test
fun getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() {
server.expect(MockRestRequestMatchers.requestTo("/greet/details"))
.andRespond(MockRestResponseCreators.withSuccess("hello", MediaType.TEXT_PLAIN))
val greeting = service.callRestService()
assertThat(greeting).isEqualTo("hello")
}
}
當在測試中的 beans 中使用 RestClient.Builder
,或在使用 RestTemplateBuilder
而不呼叫 rootUri(String rootURI)
時,完整 URI 必須在 MockRestServiceServer
期望中使用,如下列範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.client.MockRestServiceServer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
@RestClientTest(RemoteVehicleDetailsService.class)
class MyRestClientServiceTests {
@Autowired
private RemoteVehicleDetailsService service;
@Autowired
private MockRestServiceServer server;
@Test
void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() {
this.server.expect(requestTo("https://example.com/greet/details"))
.andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
String greeting = this.service.callRestService();
assertThat(greeting).isEqualTo("hello");
}
}
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.client.RestClientTest
import org.springframework.http.MediaType
import org.springframework.test.web.client.MockRestServiceServer
import org.springframework.test.web.client.match.MockRestRequestMatchers
import org.springframework.test.web.client.response.MockRestResponseCreators
@RestClientTest(RemoteVehicleDetailsService::class)
class MyRestClientServiceTests(
@Autowired val service: RemoteVehicleDetailsService,
@Autowired val server: MockRestServiceServer) {
@Test
fun getVehicleDetailsWhenResultIsSuccessShouldReturnDetails() {
server.expect(MockRestRequestMatchers.requestTo("https://example.com/greet/details"))
.andRespond(MockRestResponseCreators.withSuccess("hello", MediaType.TEXT_PLAIN))
val greeting = service.callRestService()
assertThat(greeting).isEqualTo("hello")
}
}
自動配置 Spring REST Docs 測試
您可以使用 @AutoConfigureRestDocs
註解,在您的測試中搭配 Mock MVC、REST Assured 或 WebTestClient 使用 Spring REST Docs。它消除了 Spring REST Docs 中 JUnit 擴充功能的需要。
@AutoConfigureRestDocs
可以用於覆寫預設輸出目錄(如果您使用 Maven 則為 target/generated-snippets
,如果您使用 Gradle 則為 build/generated-snippets
)。它也可以用於配置任何已記錄 URI 中顯示的主機、scheme 和埠。
使用 Mock MVC 自動配置 Spring REST Docs 測試
@AutoConfigureRestDocs
自訂了 MockMvc
bean,以便在測試基於 servlet 的 Web 應用程式時使用 Spring REST Docs。您可以使用 @Autowired
注入它,並在您的測試中使用它,就像您通常在使用 Mock MVC 和 Spring REST Docs 時一樣,如下列範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
class MyUserDocumentationTests {
@Autowired
private MockMvc mvc;
@Test
void listUsers() throws Exception {
this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andDo(document("list-users"));
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.http.MediaType
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
@WebMvcTest(UserController::class)
@AutoConfigureRestDocs
class MyUserDocumentationTests(@Autowired val mvc: MockMvc) {
@Test
fun listUsers() {
mvc.perform(MockMvcRequestBuilders.get("/users").accept(MediaType.TEXT_PLAIN))
.andExpect(MockMvcResultMatchers.status().isOk)
.andDo(MockMvcRestDocumentation.document("list-users"))
}
}
如果您需要比 @AutoConfigureRestDocs
的屬性提供的更多 Spring REST Docs 配置控制,則可以使用 RestDocsMockMvcConfigurationCustomizer
bean,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsMockMvcConfigurationCustomizer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer;
import org.springframework.restdocs.templates.TemplateFormats;
@TestConfiguration(proxyBeanMethods = false)
public class MyRestDocsConfiguration implements RestDocsMockMvcConfigurationCustomizer {
@Override
public void customize(MockMvcRestDocumentationConfigurer configurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
}
}
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsMockMvcConfigurationCustomizer
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer
import org.springframework.restdocs.templates.TemplateFormats
@TestConfiguration(proxyBeanMethods = false)
class MyRestDocsConfiguration : RestDocsMockMvcConfigurationCustomizer {
override fun customize(configurer: MockMvcRestDocumentationConfigurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown())
}
}
如果您想利用 Spring REST Docs 對參數化輸出目錄的支援,則可以建立 RestDocumentationResultHandler
bean。自動配置會使用此結果處理程序呼叫 alwaysDo
,從而導致每個 MockMvc
呼叫自動產生預設程式碼片段。以下範例顯示了如何定義 RestDocumentationResultHandler
-
Java
-
Kotlin
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
@TestConfiguration(proxyBeanMethods = false)
public class MyResultHandlerConfiguration {
@Bean
public RestDocumentationResultHandler restDocumentation() {
return MockMvcRestDocumentation.document("{method-name}");
}
}
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler
@TestConfiguration(proxyBeanMethods = false)
class MyResultHandlerConfiguration {
@Bean
fun restDocumentation(): RestDocumentationResultHandler {
return MockMvcRestDocumentation.document("{method-name}")
}
}
使用 WebTestClient 自動配置 Spring REST Docs 測試
在測試反應式 Web 應用程式時,@AutoConfigureRestDocs
也可以與 WebTestClient
一起使用。您可以使用 @Autowired
注入它,並在您的測試中使用它,就像您通常在使用 @WebFluxTest
和 Spring REST Docs 時一樣,如下列範例所示
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;
@WebFluxTest
@AutoConfigureRestDocs
class MyUsersDocumentationTests {
@Autowired
private WebTestClient webTestClient;
@Test
void listUsers() {
this.webTestClient
.get().uri("/")
.exchange()
.expectStatus()
.isOk()
.expectBody()
.consumeWith(document("list-users"));
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
import org.springframework.test.web.reactive.server.WebTestClient
@WebFluxTest
@AutoConfigureRestDocs
class MyUsersDocumentationTests(@Autowired val webTestClient: WebTestClient) {
@Test
fun listUsers() {
webTestClient
.get().uri("/")
.exchange()
.expectStatus()
.isOk
.expectBody()
.consumeWith(WebTestClientRestDocumentation.document("list-users"))
}
}
如果您需要比 @AutoConfigureRestDocs
的屬性提供的更多 Spring REST Docs 配置控制,則可以使用 RestDocsWebTestClientConfigurationCustomizer
bean,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsWebTestClientConfigurationCustomizer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer;
@TestConfiguration(proxyBeanMethods = false)
public class MyRestDocsConfiguration implements RestDocsWebTestClientConfigurationCustomizer {
@Override
public void customize(WebTestClientRestDocumentationConfigurer configurer) {
configurer.snippets().withEncoding("UTF-8");
}
}
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsWebTestClientConfigurationCustomizer
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer
@TestConfiguration(proxyBeanMethods = false)
class MyRestDocsConfiguration : RestDocsWebTestClientConfigurationCustomizer {
override fun customize(configurer: WebTestClientRestDocumentationConfigurer) {
configurer.snippets().withEncoding("UTF-8")
}
}
如果您想利用 Spring REST Docs 對參數化輸出目錄的支援,則可以使用 WebTestClientBuilderCustomizer
來為每個實體交換結果配置 consumer。以下範例顯示了如何定義這樣的 WebTestClientBuilderCustomizer
-
Java
-
Kotlin
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;
@TestConfiguration(proxyBeanMethods = false)
public class MyWebTestClientBuilderCustomizerConfiguration {
@Bean
public WebTestClientBuilderCustomizer restDocumentation() {
return (builder) -> builder.entityExchangeResultConsumer(document("{method-name}"));
}
}
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
import org.springframework.test.web.reactive.server.WebTestClient
@TestConfiguration(proxyBeanMethods = false)
class MyWebTestClientBuilderCustomizerConfiguration {
@Bean
fun restDocumentation(): WebTestClientBuilderCustomizer {
return WebTestClientBuilderCustomizer { builder: WebTestClient.Builder ->
builder.entityExchangeResultConsumer(
WebTestClientRestDocumentation.document("{method-name}")
)
}
}
}
使用 REST Assured 自動配置 Spring REST Docs 測試
@AutoConfigureRestDocs
使 RequestSpecification
bean 可用於您的測試,該 bean 預先配置為使用 Spring REST Docs。您可以使用 @Autowired
注入它,並在您的測試中使用它,就像您通常在使用 REST Assured 和 Spring REST Docs 時一樣,如下列範例所示
-
Java
-
Kotlin
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
class MyUserDocumentationTests {
@Test
void listUsers(@Autowired RequestSpecification documentationSpec, @LocalServerPort int port) {
given(documentationSpec)
.filter(document("list-users"))
.when()
.port(port)
.get("/")
.then().assertThat()
.statusCode(is(200));
}
}
import io.restassured.RestAssured
import io.restassured.specification.RequestSpecification
import org.hamcrest.Matchers
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.server.LocalServerPort
import org.springframework.restdocs.restassured.RestAssuredRestDocumentation
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs
class MyUserDocumentationTests {
@Test
fun listUsers(@Autowired documentationSpec: RequestSpecification?, @LocalServerPort port: Int) {
RestAssured.given(documentationSpec)
.filter(RestAssuredRestDocumentation.document("list-users"))
.`when`()
.port(port)["/"]
.then().assertThat()
.statusCode(Matchers.`is`(200))
}
}
如果您需要比 @AutoConfigureRestDocs
的屬性提供的更多 Spring REST Docs 配置控制,則可以使用 RestDocsRestAssuredConfigurationCustomizer
bean,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsRestAssuredConfigurationCustomizer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.restdocs.restassured.RestAssuredRestDocumentationConfigurer;
import org.springframework.restdocs.templates.TemplateFormats;
@TestConfiguration(proxyBeanMethods = false)
public class MyRestDocsConfiguration implements RestDocsRestAssuredConfigurationCustomizer {
@Override
public void customize(RestAssuredRestDocumentationConfigurer configurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
}
}
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsRestAssuredConfigurationCustomizer
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.restdocs.restassured.RestAssuredRestDocumentationConfigurer
import org.springframework.restdocs.templates.TemplateFormats
@TestConfiguration(proxyBeanMethods = false)
class MyRestDocsConfiguration : RestDocsRestAssuredConfigurationCustomizer {
override fun customize(configurer: RestAssuredRestDocumentationConfigurer) {
configurer.snippets().withTemplateFormat(TemplateFormats.markdown())
}
}
自動配置 Spring Web Services 測試
自動配置 Spring Web Services 用戶端測試
您可以使用 @WebServiceClientTest
來測試使用 Spring Web Services 專案呼叫 web services 的應用程式。預設情況下,它會配置 mock WebServiceServer
bean 並自動自訂您的 WebServiceTemplateBuilder
。(有關將 Web Services 與 Spring Boot 一起使用的更多資訊,請參閱Web Services。)
關於 @WebServiceClientTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了 @WebServiceClientTest
註解的使用
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.webservices.client.WebServiceClientTest;
import org.springframework.ws.test.client.MockWebServiceServer;
import org.springframework.xml.transform.StringSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ws.test.client.RequestMatchers.payload;
import static org.springframework.ws.test.client.ResponseCreators.withPayload;
@WebServiceClientTest(SomeWebService.class)
class MyWebServiceClientTests {
@Autowired
private MockWebServiceServer server;
@Autowired
private SomeWebService someWebService;
@Test
void mockServerCall() {
this.server
.expect(payload(new StringSource("<request/>")))
.andRespond(withPayload(new StringSource("<response><status>200</status></response>")));
assertThat(this.someWebService.test())
.extracting(Response::getStatus)
.isEqualTo(200);
}
}
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.webservices.client.WebServiceClientTest
import org.springframework.ws.test.client.MockWebServiceServer
import org.springframework.ws.test.client.RequestMatchers
import org.springframework.ws.test.client.ResponseCreators
import org.springframework.xml.transform.StringSource
@WebServiceClientTest(SomeWebService::class)
class MyWebServiceClientTests(@Autowired val server: MockWebServiceServer, @Autowired val someWebService: SomeWebService) {
@Test
fun mockServerCall() {
server
.expect(RequestMatchers.payload(StringSource("<request/>")))
.andRespond(ResponseCreators.withPayload(StringSource("<response><status>200</status></response>")))
assertThat(this.someWebService.test()).extracting(Response::status).isEqualTo(200)
}
}
自動配置 Spring Web Services 伺服器測試
您可以使用 @WebServiceServerTest
來測試使用 Spring Web Services 專案實作 web services 的應用程式。預設情況下,它會配置 MockWebServiceClient
bean,可用於呼叫您的 web service endpoints。(有關將 Web Services 與 Spring Boot 一起使用的更多資訊,請參閱Web Services。)
關於 @WebServiceServerTest 啟用的自動配置設定列表,可以在附錄中找到。 |
以下範例顯示了 @WebServiceServerTest
註解的使用
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.webservices.server.WebServiceServerTest;
import org.springframework.ws.test.server.MockWebServiceClient;
import org.springframework.ws.test.server.RequestCreators;
import org.springframework.ws.test.server.ResponseMatchers;
import org.springframework.xml.transform.StringSource;
@WebServiceServerTest(ExampleEndpoint.class)
class MyWebServiceServerTests {
@Autowired
private MockWebServiceClient client;
@Test
void mockServerCall() {
this.client
.sendRequest(RequestCreators.withPayload(new StringSource("<ExampleRequest/>")))
.andExpect(ResponseMatchers.payload(new StringSource("<ExampleResponse>42</ExampleResponse>")));
}
}
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.webservices.server.WebServiceServerTest
import org.springframework.ws.test.server.MockWebServiceClient
import org.springframework.ws.test.server.RequestCreators
import org.springframework.ws.test.server.ResponseMatchers
import org.springframework.xml.transform.StringSource
@WebServiceServerTest(ExampleEndpoint::class)
class MyWebServiceServerTests(@Autowired val client: MockWebServiceClient) {
@Test
fun mockServerCall() {
client
.sendRequest(RequestCreators.withPayload(StringSource("<ExampleRequest/>")))
.andExpect(ResponseMatchers.payload(StringSource("<ExampleResponse>42</ExampleResponse>")))
}
}
額外的自動配置與切片
每個切片都提供一個或多個 @AutoConfigure…
註解,這些註解明確定義了應作為切片一部分包含的自動配置。可以透過建立自訂的 @AutoConfigure…
註解或將 @ImportAutoConfiguration
新增到測試中,在每個測試的基礎上新增額外的自動配置,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration.class)
class MyJdbcTests {
}
import org.springframework.boot.autoconfigure.ImportAutoConfiguration
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest
@JdbcTest
@ImportAutoConfiguration(IntegrationAutoConfiguration::class)
class MyJdbcTests
請確保不要使用常規的 @Import 註解來匯入自動配置,因為 Spring Boot 會以特定方式處理它們。 |
或者,可以透過將額外的自動配置註冊在儲存在 META-INF/spring
中的檔案中,為任何切片註解的使用新增它們,如下列範例所示
com.example.IntegrationAutoConfiguration
在此範例中,com.example.IntegrationAutoConfiguration
在每個使用 @JdbcTest
註解的測試中啟用。
您可以在此檔案中使用 # 註解。 |
只要切片或 @AutoConfigure… 註解使用 @ImportAutoConfiguration 進行元註解,就可以使用這種方式進行自訂。 |
使用者配置與切片
然後,重要的是不要在應用程式的主要類別中充斥特定於其功能特定領域的配置設定。
假設您正在使用 Spring Data MongoDB,您依賴於它的自動配置,並且您已啟用稽核。您可以如下所示定義您的 @SpringBootApplication
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
@SpringBootApplication
@EnableMongoAuditing
public class MyApplication {
// ...
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.data.mongodb.config.EnableMongoAuditing
@SpringBootApplication
@EnableMongoAuditing
class MyApplication {
// ...
}
由於此類別是測試的來源配置,因此任何切片測試實際上都會嘗試啟用 Mongo 稽核,這絕對不是您想要做的。建議的方法是將該特定於領域的配置移動到與您的應用程式位於同一層級的單獨 @Configuration
類別,如下列範例所示
-
Java
-
Kotlin
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
@Configuration(proxyBeanMethods = false)
@EnableMongoAuditing
public class MyMongoConfiguration {
// ...
}
import org.springframework.context.annotation.Configuration
import org.springframework.data.mongodb.config.EnableMongoAuditing
@Configuration(proxyBeanMethods = false)
@EnableMongoAuditing
class MyMongoConfiguration {
// ...
}
根據應用程式的複雜性,您可以為您的自訂設定使用單個 @Configuration 類別,也可以為每個領域區域使用一個類別。後一種方法讓您可以在必要時使用 @Import 註解在您的其中一個測試中啟用它。有關您可能想要為切片測試啟用特定 @Configuration 類別的更多詳細資訊,請參閱此操作指南章節。 |
測試切片排除掃描 @Configuration
類別。例如,對於 @WebMvcTest
,以下配置將不會在測試切片載入的應用程式上下文中包含給定的 WebMvcConfigurer
bean
-
Java
-
Kotlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration(proxyBeanMethods = false)
public class MyWebConfiguration {
@Bean
public WebMvcConfigurer testConfigurer() {
return new WebMvcConfigurer() {
// ...
};
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration(proxyBeanMethods = false)
class MyWebConfiguration {
@Bean
fun testConfigurer(): WebMvcConfigurer {
return object : WebMvcConfigurer {
// ...
}
}
}
但是,以下配置將導致測試切片載入自訂的 WebMvcConfigurer
。
-
Java
-
Kotlin
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class MyWebMvcConfigurer implements WebMvcConfigurer {
// ...
}
import org.springframework.stereotype.Component
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Component
class MyWebMvcConfigurer : WebMvcConfigurer {
// ...
}
另一個造成混淆的來源是類別路徑掃描。假設您以合理的方式組織了程式碼,但您需要掃描額外的套件。您的應用程式可能類似於以下程式碼
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan({ "com.example.app", "com.example.another" })
public class MyApplication {
// ...
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.ComponentScan
@SpringBootApplication
@ComponentScan("com.example.app", "com.example.another")
class MyApplication {
// ...
}
這樣做會有效地覆寫預設的元件掃描指令,其副作用是不論您選擇哪個切片,都會掃描這兩個套件。例如,@DataJpaTest
似乎會突然掃描您應用程式的元件和使用者組態。同樣地,將自訂指令移到單獨的類別是解決此問題的好方法。
如果這不是您的選項,您可以在測試階層結構中的某處建立一個 @SpringBootConfiguration ,以便改為使用它。或者,您可以為您的測試指定一個來源,這會停用尋找預設來源的行為。 |
使用 Spock 測試 Spring Boot 應用程式
Spock 2.2 或更高版本可用於測試 Spring Boot 應用程式。為此,請將 Spock 的 spock-spring
模組的 -groovy-4.0
版本相依性新增至您應用程式的建置中。spock-spring
將 Spring 的測試框架整合到 Spock 中。請參閱 Spock Spring 模組的文件 以取得更多詳細資訊。