更進一步
VMware 提供培訓和認證,助你加速進步。
瞭解更多閱讀時長:約 6 分鐘 編碼時長:約 15 分鐘
如果你一直在關注本系列文章,那麼現在你已經構建了一個 Spring Boot 原型,它展示了 RSocket 中的許多特性。然而,這段程式碼並非生產級程式碼;它只是一個原型,是你在 RSocket 之旅中的一塊墊腳石。對於生產級程式碼,我期望遵循所有常規的質量保證和測試規則。因此,在本練習中,我將向你展示如何為 RSocket 響應器編寫整合測試,從而讓你離生產環境更進一步。
但首先,我說的整合測試是什麼意思?
在此上下文中,整合測試是指測試 RSocket 請求者和響應者之間的來回通訊。在這種測試期間,重要的是要驗證架構的每一層,包括網路層。
但是,整合測試可能比常規單元測試更耗時,正是因為你需要驗證每一層。它們執行時間可能更長,需要多個元件和層,並且可預測性較低。然而,整合測試還有其他好處,例如檢查你的請求者和響應者是否彼此建立連線並正常通訊。
你還會注意到,在本教程中我跳過了所有其他形式的測試。要涵蓋所有可能的測試型別需要寫一整本書!如果你正在尋找 Spring Boot 應用程式測試的更通用介紹,可以看看 Andy Wilkinson 的這段演講,或者Spring Boot 測試文件,或者線上搜尋“testing spring applications”。
背景介紹到此為止;讓我們開始測試吧!
如果你需要檢視程式碼,可以在 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。這節省了大量時間和配置工作。
你可以使用一個 RSocket 連線進行多次測試,方法是將 RSocketRequester
新增為全域性類變數,如下所示
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 響應器,你可以防止迴歸,檢查元件是否正常通訊,並更有信心地將它們交付給客戶。