領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多閱讀時間:約 6 分鐘 編碼時間:約 15 分鐘
如果您一直關注這個系列,那麼現在您已經構建了一個 Spring Boot 原型,它展示了 RSocket 中的許多功能。然而,這段程式碼不是生產程式碼;它是一個原型,是您 RSocket 之旅的一個墊腳石。對於生產程式碼,我期望所有常規的質量保證和測試規則都適用。因此,在這個練習中,我將向您展示如何編寫 RSocket 響應器的整合測試,以便您離生產更近一步。
但首先,我所說的整合測試是什麼意思?
在這種上下文中,整合測試意味著測試 RSocket 請求者和響應者之間的雙向通訊。在這樣的測試中,重要的是要鍛鍊架構的每一層,包括網路。
但是,整合測試可能比常規單元測試更昂貴,正是因為您鍛鍊了每一層。它們執行時間更長,需要多個元件和層,並且可能更不可預測。然而,整合測試還有其他好處,例如檢查您的請求者和響應者是否相互聯絡並正確通訊。
您還會注意到,在本教程中我跳過了所有其他形式的測試。要涵蓋所有可能的測試型別,需要一整本書!如果您正在尋找 Spring Boot 應用程式測試的更一般性介紹,請嘗試 Andy Wilkinson 的這次演講,或者Spring Boot 測試文件,或者線上搜尋“測試 Spring 應用程式”。
背景知識就足夠了;讓我們開始測試吧!
如果您需要檢視程式碼,可以在GitHub上找到。如果您想了解本系列文章的其餘部分,它們都列在 Spring 網站我的頁面上。
在您的 rsocket-server 專案中,在 /src/test/java/io/pivotal/rsocketserver/ 資料夾中,建立一個新的整合測試類 RSocketClientToServerITest。最簡單的方法通常是在您的 IDE 中完成。
建議的命名約定是每個整合測試類名都以後綴 'ITest' 結尾。由此產生的檔名 <your-class-name>ITest.java 更易於閱讀,並允許 Maven 過濾您的整合測試——您稍後將使用這項技術。請務必像這樣用 @SpringBootTest 註解您的新類
@SpringBootTest
public class RSocketClientToServerITest {
// test code goes here
}
@SpringBootTest 註解允許 Spring Boot 配置您測試所需的一切,包括 RSocket。它節省了大量時間和大量配置。
您可以透過新增 RSocketRequester 作為全域性類變數來為多個測試使用單個 RSocket 連線,如下所示
private static RSocketRequester requester;
在您的測試執行之前,您必須為這個請求者建立一個工作連線。JUnit5 中的 @BeforeAll 註解非常適合執行這些一次性設定任務。將以下方法新增到您的類中
@BeforeAll
public static void setupOnce(@Autowired RSocketRequester.Builder builder, @Value("${spring.rsocket.server.port}") Integer port) {
requester = builder
.connectTcp("localhost", port)
.block();
}
您會注意到方法簽名期望 Spring Boot 從 Spring 應用程式上下文中傳遞一些項。RSocketRequester.Builder 簡化了 RSocket 連線的建立,並且需要響應者的埠號來建立連結。埠號來自 application.properties 檔案中的 spring.rsocket.server.port 值。
現在請求者已就位;您已準備好新增第一個整合測試。在此測試期間發生兩件事。首先,請求者向響應者發出呼叫,帶有命名路由和附加資料。其次,驗證收到的響應行為是否完全符合預期。程式碼如下所示
@Test
public void testRequestGetsResponse() {
// Send a request message (1)
Mono<Message> result = requester
.route("request-response")
.data(new Message("TEST", "Request"))
.retrieveMono(Message.class);
// Verify that the response message contains the expected data (2)
StepVerifier
.create(result)
.consumeNextWith(message -> {
assertThat(message.getOrigin()).isEqualTo(RSocketController.SERVER); assertThat(message.getInteraction()).isEqualTo(RSocketController.RESPONSE);
assertThat(message.getIndex()).isEqualTo(0);})
.verifyComplete();
}
在第一部分 (1) 中,使用的路由是 "request-response",資料是一個新的 Message 物件。來自響應者(您的 RSocketController)的結果是型別為 Message 的 Mono。
在第二部分 (2) 中,StepVerifier 類檢查 mono 的行為是否符合預期。在 consumeWithNext() 方法中,一個函式使用 AssertJ 的斷言方法檢查返回訊息的內容。verifyComplete() 方法確保互動按預期完成。
其他互動的測試方式相同。這裡不再贅述每種互動型別的測試,請檢視 GitHub 上的完整測試。
一旦測試周期完成,您可以關閉不再需要的任何資源。在這種情況下,這意味著處理 RSocket 請求者。新增一個方法來執行此操作,並使用 @AfterAll 註解該方法,如下所示
@AfterAll
public static void tearDownOnce() {
requester.rsocket().dispose();
}
執行整合測試可能需要一段時間,並且它們可能因意外原因(例如網路中斷)而失敗。因此,隔離您的整合測試以便您可以選擇性地執行它們是很有意義的。Maven 使用 Failsafe 外掛來實現這一點。
要配置 failsafe,請在您的 pom.xml 中新增以下外掛配置。此配置告訴 Maven 使用 failsafe 執行所有以 'ITest.java' 字尾結尾的測試。它還告訴 Maven 在 integration-test 或 verify 生命週期階段執行這些測試。
<plugins>
<!-- other plugins -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>**/*ITest.java</includes>
</configuration>
</plugin>
您還需要防止整合測試與常規單元測試一起執行,因此新增以下 surefire 配置以將其排除
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*ITest.java</exclude>
</excludes>
</configuration>
</plugin>
<!-- other plugins -->
</plugins>
您現在可以在終端控制檯中執行您的整合測試。Maven 使用 integration-test 目標來實現此目的。
./mvnw clean integration-test
Maven 現在執行您的整合測試,結果將顯示在控制檯中。
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 23.582 s - in io.pivotal.rsocketserver.RSocketClientToServerITest
2020-05-19 10:43:27.512 INFO 39250 --- [extShutdownHook] i.p.rsocketserver.RSocketController : Detaching all remaining clients...
2020-05-19 10:43:27.513 INFO 39250 --- [extShutdownHook] i.p.rsocketserver.RSocketController : Shutting down.
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
您還可以整合測試客戶端響應者。所需程式碼比上面略複雜。主要涉及建立一個虛假的請求者元件,其中包含與您在此處看到的類似的 StepVerifier 測試。我鼓勵您檢視原始碼,而不是逐行描述程式碼。
整合測試是產品生產路徑上的關鍵組成部分。透過這種方式測試您的 RSocket 響應者,您可以防止迴歸,檢查元件是否正常通訊,並更自信地將它們交付給您的客戶。