此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

测试客户端应用程序

要测试使用RestClientRestTemplate,您可以使用模拟 Web 服务器,例如 OkHttp MockWebServerWireMock。模拟 Web 服务器像常规 Web 服务器一样接受通过 HTTP 的请求 server,这意味着您可以使用同样配置的相同 HTTP 客户端进行测试 与生产中的方式相同,这很重要,因为通常有细微的 不同客户端处理网络 I/O 的方式的差异。模拟的另一个优点 Web 服务器能够在 运输水平,结合生产中使用的客户端。spring-doc.cadn.net.cn

除了专用的模拟 Web 服务器外,Spring Framework 历来还提供了 用于测试的内置选项RestClientRestTemplate通过MockRestServiceServer. 这依赖于使用自定义ClientHttpRequestFactory由模拟服务器支持,该服务器又设置为预期请求并发送“存根” responses,以便您可以专注于单独测试代码,而无需运行服务器。spring-doc.cadn.net.cn

MockRestServiceServer早于模拟 Web 服务器的存在。目前,我们 建议使用模拟 Web 服务器对传输层进行更完整的测试,并且 网络条件。

以下示例显示了使用MockRestServiceServer:spring-doc.cadn.net.cn

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());

// Test code that uses the above RestTemplate ...

mockServer.verify();
val restTemplate = RestTemplate()

val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess())

// Test code that uses the above RestTemplate ...

mockServer.verify()

在前面的示例中,MockRestServiceServer(客户端 REST 的中心类 tests) 配置RestTemplate使用自定义ClientHttpRequestFactory那 根据预期断言实际请求并返回“存根”响应。在这个 case 时,我们期望请求/greeting并希望返回 200 响应text/plain内容。我们可以将其他预期请求和存根响应定义为 需要。当我们定义预期请求和存根响应时,RestTemplate可以 像往常一样在客户端代码中使用。测试结束时,mockServer.verify()可以 用于验证所有期望是否已得到满足。spring-doc.cadn.net.cn

默认情况下,请求按声明预期的顺序进行。你 可以设置ignoreExpectOrder选项,在这种情况下,所有 检查期望值(按顺序)以查找给定请求的匹配项。这意味着 允许以任何顺序提出请求。以下示例使用ignoreExpectOrder:spring-doc.cadn.net.cn

server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build()

即使默认情况下使用无序请求,每个请求也只允许运行一次。 这expect方法提供了一个重载的变体,该变体接受ExpectedCount指定计数范围的参数(例如,once,manyTimes,max,min,between,依此类推)。以下示例使用times:spring-doc.cadn.net.cn

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess());
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess());

// ...

mockServer.verify();
val restTemplate = RestTemplate()

val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess())
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess())

// ...

mockServer.verify()

请注意,当ignoreExpectOrder未设置(默认值),因此请求 是预期的,则该顺序仅适用于任何 预期请求。例如,如果“/something”需要两次,然后是 “/somewhere”三次,那么在出现之前应该有对“/something”的请求 对“/somewhere”的请求,但是,除了随后的“/something”和“/somewhere”之外, 请求可以随时提出。spring-doc.cadn.net.cn

作为上述所有方法的替代方法,客户端测试支持还提供了ClientHttpRequestFactory您可以配置到RestTemplate自 将其绑定到MockMvc实例。这允许使用实际的服务器端处理请求 逻辑,但不运行服务器。以下示例显示了如何执行此作:spring-doc.cadn.net.cn

MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));

// Test code that uses the above RestTemplate ...
val mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build()
restTemplate = RestTemplate(MockMvcClientHttpRequestFactory(mockMvc))

// Test code that uses the above RestTemplate ...

在某些情况下,可能需要对远程服务执行实际调用 嘲笑回应。以下示例显示了如何通过ExecutingResponseCreator:spring-doc.cadn.net.cn

RestTemplate restTemplate = new RestTemplate();

// Create ExecutingResponseCreator with the original request factory
ExecutingResponseCreator withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory());

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/profile")).andRespond(withSuccess());
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse);

// Test code that uses the above RestTemplate ...

mockServer.verify();
val restTemplate = RestTemplate()

// Create ExecutingResponseCreator with the original request factory
val withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory())

val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(requestTo("/profile")).andRespond(withSuccess())
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse)

// Test code that uses the above RestTemplate ...

mockServer.verify()

在前面的示例中,我们创建了ExecutingResponseCreator使用ClientHttpRequestFactoryRestTemplate 以前 MockRestServiceServer取代 它有一个不同的嘲笑反应。 然后我们用两种响应来定义期望:spring-doc.cadn.net.cn

在第二种情况下,请求通过ClientHttpRequestFactory那是 早些时候捕获。这会生成一个响应,例如,该响应可能来自实际的远程服务器, 取决于RestTemplate最初配置。spring-doc.cadn.net.cn

静态导入

与服务器端测试一样,用于客户端测试的流畅 API 需要一些静态 进口。通过搜索很容易找到这些MockRest*.Eclipse 用户应该添加MockRestRequestMatchers.*MockRestResponseCreators.*如 “最喜欢的静态成员” 在 Java → 编辑器下的 Eclipse 首选项中→内容辅助→收藏夹。这允许在键入 的第一个字符后使用内容辅助静态方法名称。其他 IDE(例如 IntelliJ)可能不需要任何其他 配置。 检查静态成员是否支持代码完成。spring-doc.cadn.net.cn

客户端 REST 测试的更多示例

Spring MVC Test 自己的测试包括示例客户端 REST 测试的测试spring-doc.cadn.net.cn