你可以使用客户端测试(client-side)来测试内部使用 RestTemplate 的代码。这个想法是声明预期的请求并提供 「存根 (stub)」响应,这样你就可以专注于孤立地测试代码(也就是说,不运行服务器)。下面的例子显示了如何做到这一点。

  1. RestTemplate restTemplate = new RestTemplate();
  2. MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
  3. mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());
  4. // 使用上述 RestTemplate 的测试代码...
  5. mockServer.verify();

在前面的例子中,MockRestServiceServer(客户端 REST 测试的中心类)用一个自定义的 ClientHttpRequestFactory 来配置 RestTemplate,该 Factory 根据预期断定实际请求并返回 「存根」响应。在这种情况下,我们期待一个对 /greeting的请求,并希望返回一个带有text/plain内容的 200 响应。我们可以根据需要定义额外的预期请求和存根响应。当我们定义了预期请求和存根响应后,RestTemplate 可以像往常一样在客户端代码中使用。在测试结束时,可以使用 mockServer.verify()来验证所有的预期都得到了满足。

默认情况下,请求是按照期望值声明的顺序被期望的。你可以在构建服务器时设置 ignoreExpectOrder选项,在这种情况下,所有的期望值都会被检查(按顺序)以找到与给定请求的匹配。这意味着允许请求以任何顺序出现。下面的例子使用了 ignoreExpectOrder

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

即使默认情况下是无序的请求,每个请求也只允许运行一次。expect 方法提供了一个重载变体,它接受一个指定计数范围的 ExpectedCount 参数(例如,once, manyTimes, max, min, between,等等)。下面的例子使用了次数:

  1. RestTemplate restTemplate = new RestTemplate();
  2. MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
  3. mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess());
  4. mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess());
  5. // ...
  6. mockServer.verify();

注意,当 ignoreExpectOrder 没有被设置时(默认情况),因此,请求是按照声明的顺序被预期的,那么这个顺序只适用于任何预期请求中的第一个。例如,如果 /something 被期望两次,然后是 /somewhere三次,那么在有 /somewhere 的请求之前应该有一个 /something 的请求,但是,除了随后的 /something/somewhere之外,请求可以在任何时候出现。

作为上述所有的替代方案,客户端测试支持也提供了一个 ClientHttpRequestFactory 实现,你可以将其配置到 RestTemplate 中,将其绑定到 MockMvc 实例上。这允许使用实际的服务器端逻辑来处理请求,但不需要运行一个服务器。下面的例子展示了如何做到这一点。

  1. MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
  2. this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));
  3. // Test code that uses the above RestTemplate ...

静态导入

和服务器端的测试一样,客户端测试的流畅 API 需要一些静态导入。通过搜索 MockRest*,可以很容易地找到这些。Eclipse 用户应该将MockRestRequestMatchers.*MockRestResponseCreators.* 使用 Java → Editor → Content Assist → Favorites 配置。这允许在输入静态方法名称的第一个字符后使用内容辅助。其他 IDE(如 IntelliJ)可能不需要任何额外的配置。检查对静态成员的代码完成的支持情况。

客户端 REST 测试的更多示例

Spring MVC Test 自己的测试包括客户端 REST 测试的示例测试。