先人一步
VMware 提供培訓和認證,以加速您的進步。
瞭解更多如果您的應用程式在執行時連線到 RSocket 伺服器,您如何測試它?我們需要一種方法讓測試啟動伺服器並告訴我們它正在偵聽的位置,然後我們需要能夠註冊請求和響應示例(也就是“合約”)。這就是這個 專案 提供的功能 - 它就像 Wiremock,但用於 RSocket。
使用該專案最簡單的方法是作為 JUnit (Jupiter) 擴充套件,例如
@SpringBootTest
@ExtendWith(RSocketServerExtension.class)
class SocketsApplicationTests {
...
}
安裝此擴充套件後,Spring Boot 測試將在 RSocket 伺服器上執行,該伺服器監聽由 test.rsocket.server.port
給出的埠,因此測試可以直接連線到它,或者(更可能)它正在測試的程式碼將連線到它。您可能需要透過 @SpringBootTest
註釋告訴它連線的位置,例如,如果應用程式在執行時查詢名為 rsocket.port
的屬性
@SpringBootTest("rsocket.port=${test.rsocket.server.port}")
@ExtendWith(RSocketServerExtension.class)
class SocketsApplicationTests {
...
}
測試方法可以注入 RSocketMessageCatalog
或 RSocketMessageRegistry
,然後使用它們來設定或檢查伺服器的狀態。預設情況下,伺服器從類路徑下的 /catalog/*.json
讀取 JSON 合約,因此您可以在本地或與 sarver 共享的測試庫中設定這些合約。JSON 的結構映象儲存在 RSocketMessageCatalog
中的 MessageMapping
。這是一個例子(請求和響應只是 JSON 物件)
{
"pattern": "events.response.*",
"frameType": "REQUEST_RESPONSE",
"request": {
"origin": "Client"
},
"response": {
"origin": "Server",
"interaction": "Response",
"index": 0
}
}
此對映將匹配路由上與模式匹配的任何 REQUEST_RESPONSE
幀型別,並且該路由還具有一個 "origin" 欄位等於 "Client" 的請求。您還可以透過新增萬用字元來匹配請求中欄位的模式。或者您可以省略請求僅匹配路由。如果幀型別是 REQUEST_RESPONSE
,則響應是單值的。如果 frametype 是 REQUEST_STREAM
,您可以提供多值 "responses",例如
{
"pattern": "my.stream.route",
"frameType": "REQUEST_STREAM",
"responses": [
{
"origin": "Server",
"interaction": "Stream",
"index": 0
},
{
"origin": "Server",
"interaction": "Stream",
"index": 1
},
{
"origin": "Server",
"interaction": "Stream",
"index": 2
}
]
}
此外,您可以指定一個整數字段 "repeat" 來重複響應以形成更長的流。如果幀型別是 REQUEST_FNF
,則沒有響應,並且請求將被忽略。最後,如果幀型別是 REQUEST_CHANNEL
,則對映 JSON 的格式與 REQUEST_STREAM
相同,不同之處在於每次從輸入流中收到訊息時,都會再次發出輸出流。
如果您的處理規則需要更大的靈活性,您可以從介面中方便的靜態工廠方法建立自己的 MessageMapping
。您可以提供一個處理函式(除了 fire and forget 的情況),一個要匹配的模式,以及可選的要匹配的請求。這些方法可以用於動態註冊對映以定義伺服器在執行時的預期行為。
您可以透過從目錄中獲取 MessageMapping
來檢查伺服器的狀態,然後呼叫其中一個 drain()
方法來耗盡已收到的請求。例如
@SpringBootTest
@ExtendWith(RSocketServerExtension.class)
class DynamicRouteTests {
private RSocketRequester rsocketRequester;
public DynamicRouteTests(@Autowired RSocketRequester.Builder rsocketRequesterBuilder,
@Value("${test.rsocket.server.port:7000}") int port) {
rsocketRequester = rsocketRequesterBuilder.tcp("localhost", port);
}
@Test
void response(RSocketMessageRegistry catalog) {
MessageMapping response = MessageMapping.response("response")
.response(new Foo("Server", "Response"));
catalog.register(response);
assertThat(rsocketRequester.route("response").data(new Foo("Client", "Request"))
.retrieveMono(Foo.class).doOnNext(foo -> {
System.err.println(foo);
assertThat(foo.getOrigin()).isEqualTo("Server");
}).block()).isNotNull();
assertThat(response.drain()).hasSize(1);
assertThat(response.drain()).hasSize(0);
}
}
這裡的程式碼仍然是一個原型,但它已經可能非常有用。所以試試看併發送反饋,也許我們可以讓它成熟到我們可以釋出它的程度。