領先一步
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 合約,因此您可以在本機或在與伺服器共用的測試庫中設定這些合約。 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
,則回應是單值的。 如果框架類型為 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
相同,只是每次從輸入串流接收到訊息時,都會再次發出輸出串流。
如果您需要更靈活的處理規則,您可以從介面中方便的靜態 factory 方法建立自己的 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);
}
}
此處的程式碼仍然只是一個原型,但它已經可能非常有用。 因此,請試用看看並發送回饋,也許我們可以使其成熟到可以發布的程度。