跳到主要内容
版本:7.0.3

测试客户端应用程序

Hunyuan 7b 中英对照 Testing Client Applications

要测试使用RestClientRestTemplate的代码,你可以使用模拟Web服务器,例如OkHttp MockWebServerWireMock。模拟Web服务器像普通服务器一样接收HTTP请求,这意味着你可以使用与生产环境中配置相同的HTTP客户端来进行测试,这一点很重要,因为不同客户端处理网络I/O的方式往往存在细微差别。模拟Web服务器的另一个优点是能够在传输层模拟特定的网络问题和条件,这与生产环境中使用的客户端相结合。

除了专门的模拟Web服务器外,从历史上看,Spring框架还提供了一个内置选项,可以通过MockRestServiceServer来测试RestClientRestTemplate。这种方法依赖于使用一个由模拟服务器支持的自定义ClientHttpRequestFactory来配置被测试的客户端,该模拟服务器会设置好预期请求并发送“存根”响应,这样你就可以专注于独立测试代码,而无需运行服务器。

提示

MockRestServiceServer出现在模拟Web服务器出现之前。目前,我们建议使用模拟Web服务器来更全面地测试传输层和网络条件。

以下示例展示了如何使用MockRestServiceServer

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();

在前面的例子中,MockRestServiceServer(用于客户端REST测试的中央类)使用一个自定义的ClientHttpRequestFactory来配置RestTemplate,该工厂会对比实际请求与预期结果,并返回“存根”响应。在这个例子中,我们期望对/greeting的请求能够得到一个包含text/plain内容的200响应。根据需要,我们还可以定义其他预期的请求和对应的存根响应。当我们定义了这些预期请求和存根响应后,就可以像往常一样在客户端代码中使用RestTemplate了。测试结束时,可以使用mockServer.verify()来验证所有预期结果是否都得到了满足。

默认情况下,请求的接收顺序应与声明的预期顺序一致。在构建服务器时,你可以设置 ignoreExpectOrder 选项,这样一来,系统会(按顺序)检查所有的预期条件,以找到与给定请求相匹配的结果。这意味着请求可以以任何顺序到达。以下示例使用了 ignoreExpectOrder

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

即使在默认情况下请求是无序的,每个请求也只允许执行一次。expect 方法提供了一个重载版本,该版本接受一个 ExpectedCount 参数,用于指定计数范围(例如,oncemanyTimesmaxminbetween 等)。以下示例使用了 times

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();

请注意,当 ignoreExpectOrder 未设置(即默认值)时,请求将按照声明的顺序进行。因此,这种顺序仅适用于第一个预期请求。例如,如果预期 “/something” 会出现两次,而 “/somewhere” 会出现三次,那么在发送 “/somewhere” 的请求之前,必须先发送 “/something” 的请求;但除此之外,“/something” 和 “/somewhere” 的后续请求可以随时到来。

作为上述所有方法的替代方案,客户端测试支持还提供了一个ClientHttpRequestFactory实现,你可以将其配置到RestTemplate中,以便与MockMvc实例绑定。这样就可以使用实际的服务器端逻辑来处理请求,而无需运行服务器。以下示例展示了如何进行这样的配置:

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

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

在某些情况下,可能有必要实际调用远程服务,而不是模拟其响应。以下示例展示了如何通过 ExecutingResponseCreator 来实现这一点:

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();

在前面的例子中,我们使用RestTemplate中的ClientHttpRequestFactory来创建ExecutingResponseCreator,然后在MockRestServiceServer用一个模拟响应的不同的实现来替换它。接着我们定义了两种响应的预期结果:

  • 对于 /profile 端点,返回一个状态码为 200 的空响应(实际上不会执行任何请求)

  • 通过调用 /quoteOfTheDay 端点获得的响应

在第二种情况下,请求是通过之前捕获的ClientHttpRequestFactory来执行的。这会生成一个响应,根据RestTemplate最初的配置方式,该响应可能来自实际的远程服务器。

静态导入

与服务器端测试一样,客户端测试的流畅API也需要一些静态导入。通过搜索MockRest*可以很容易地找到这些导入。Eclipse用户应该在Eclipse的设置中(Java → Editor → Content Assist → Favorites)将MockRestRequestMatchers.*MockRestResponseCreators.*添加为“常用静态成员”。这样在输入静态方法名称的第一个字符后就可以使用代码辅助功能了。其他IDE(如IntelliJ)可能不需要任何额外的配置。请检查它们是否支持对静态成员的代码补全功能。

客户端REST测试的更多示例

Spring MVC 测试自己包含示例测试,这些是客户端 REST 测试的示例。