你可以使用客户端测试(client-side)来测试内部使用 RestTemplate 的代码。这个想法是声明预期的请求并提供 「存根 (stub)」响应,这样你就可以专注于孤立地测试代码(也就是说,不运行服务器)。下面的例子显示了如何做到这一点。
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());
// 使用上述 RestTemplate 的测试代码...
mockServer.verify();
在前面的例子中,MockRestServiceServer(客户端 REST 测试的中心类)用一个自定义的 ClientHttpRequestFactory 来配置 RestTemplate,该 Factory 根据预期断定实际请求并返回 「存根」响应。在这种情况下,我们期待一个对 /greeting
的请求,并希望返回一个带有text/plain
内容的 200 响应。我们可以根据需要定义额外的预期请求和存根响应。当我们定义了预期请求和存根响应后,RestTemplate 可以像往常一样在客户端代码中使用。在测试结束时,可以使用 mockServer.verify()
来验证所有的预期都得到了满足。
默认情况下,请求是按照期望值声明的顺序被期望的。你可以在构建服务器时设置 ignoreExpectOrder
选项,在这种情况下,所有的期望值都会被检查(按顺序)以找到与给定请求的匹配。这意味着允许请求以任何顺序出现。下面的例子使用了 ignoreExpectOrder
:
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
即使默认情况下是无序的请求,每个请求也只允许运行一次。expect 方法提供了一个重载变体,它接受一个指定计数范围的 ExpectedCount 参数(例如,once, manyTimes, max, min, between,等等)。下面的例子使用了次数:
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 ...
静态导入
和服务器端的测试一样,客户端测试的流畅 API 需要一些静态导入。通过搜索 MockRest*
,可以很容易地找到这些。Eclipse 用户应该将MockRestRequestMatchers.*
和 MockRestResponseCreators.*
使用 Java → Editor → Content Assist → Favorites 配置。这允许在输入静态方法名称的第一个字符后使用内容辅助。其他 IDE(如 IntelliJ)可能不需要任何额外的配置。检查对静态成员的代码完成的支持情况。
客户端 REST 测试的更多示例
Spring MVC Test 自己的测试包括客户端 REST 测试的示例测试。