3.8. 测试客户端应用程序 {#spring-mvc-test-client

预计阅读时间: 7 分钟

You can use client-side tests to test code that internally uses the RestTemplate. The idea is to declare expected requests and to provide “stub” responses so that you can focus on testing the code in isolation (that is, without running a server). The following example shows how to do so:
您可以使用客户端测试来测试内部使用 RestTemplate 的代码。想法是声明预期的请求并提供“存根”响应,这样您就可以专注于单独测试代码(即,不运行服务器)。以下示例展示了如何做到这一点:

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

In the preceding example, MockRestServiceServer (the central class for client-side REST tests) configures the RestTemplate with a custom ClientHttpRequestFactory that asserts actual requests against expectations and returns “stub” responses. In this case, we expect a request to /greeting and want to return a 200 response with text/plain content. We can define additional expected requests and stub responses as needed. When we define expected requests and stub responses, the RestTemplate can be used in client-side code as usual. At the end of testing, mockServer.verify() can be used to verify that all expectations have been satisfied.
在先前的示例中, MockRestServiceServer (客户端 REST 测试的中心类)使用自定义的 RestTemplate 配置,该配置断言实际请求与预期相符,并返回“存根”响应。在这种情况下,我们期望一个请求到 /greeting ,并希望返回包含 text/plain 内容的 200 响应。我们可以根据需要定义额外的预期请求和存根响应。当我们定义预期请求和存根响应时, RestTemplate 可以在客户端代码中像往常一样使用。测试结束时, mockServer.verify() 可以用来验证所有预期是否都已满足。

By default, requests are expected in the order in which expectations were declared. You can set the ignoreExpectOrder option when building the server, in which case all expectations are checked (in order) to find a match for a given request. That means requests are allowed to come in any order. The following example uses ignoreExpectOrder:
默认情况下,期望的请求应按照声明期望的顺序进行。在构建服务器时,您可以设置 ignoreExpectOrder 选项,在这种情况下,所有期望都会按顺序检查以找到与给定请求的匹配项。这意味着请求可以以任何顺序到来。以下示例使用 ignoreExpectOrder

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

Even with unordered requests by default, each request is allowed to run once only. The expect method provides an overloaded variant that accepts an ExpectedCount argument that specifies a count range (for example, once, manyTimes, max, min, between, and so on). The following example uses times:
即使默认为无序请求,每个请求也只允许运行一次。 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();
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()

Note that, when ignoreExpectOrder is not set (the default), and, therefore, requests are expected in order of declaration, then that order applies only to the first of any expected request. For example if "/something" is expected two times followed by "/somewhere" three times, then there should be a request to "/something" before there is a request to "/somewhere", but, aside from that subsequent "/something" and "/somewhere", requests can come at any time.
请注意,当 ignoreExpectOrder 未设置(默认情况)时,因此请求应按声明顺序进行,那么这个顺序仅适用于任何预期请求中的第一个。例如,如果预期"/something" 两次,然后是"/somewhere"三次,那么在请求"/somewhere"之前应该先请求"/something",但除了这个之外,后续的"/something"和" /somewhere"请求可以随时到来。

As an alternative to all of the above, the client-side test support also provides a ClientHttpRequestFactory implementation that you can configure into a RestTemplate to bind it to a MockMvc instance. That allows processing requests using actual server-side logic but without running a server. The following example shows how to do so:
作为上述所有方法的替代方案,客户端测试支持还提供了一个 ClientHttpRequestFactory 实现,您可以将它配置到 RestTemplate 中,以将其绑定到 MockMvc 实例。这允许使用实际的服务器端逻辑处理请求,而不需要运行服务器。以下示例展示了如何做到这一点:

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 ...

(#spring-mvc-test-client-static-imports)3.8.1. Static Imports 3.8.1. 静态导入

As with server-side tests, the fluent API for client-side tests requires a few static imports. Those are easy to find by searching for MockRest*. Eclipse users should add MockRestRequestMatchers.* and MockRestResponseCreators.* as “favorite static members” in the Eclipse preferences under Java → Editor → Content Assist → Favorites. That allows using content assist after typing the first character of the static method name. Other IDEs (such IntelliJ) may not require any additional configuration.
与服务器端测试一样,客户端测试的 Fluent API 需要几个静态导入。这些可以通过搜索 MockRest* 轻松找到。Eclipse 用户应在 Eclipse 首选项下的 Java → 编辑器 → 内容辅助 → 收藏夹中将 MockRestRequestMatchers.*MockRestResponseCreators.* 添加为“收藏的静态成员”。这允许在键入静态方法名的第一个字符后使用内容辅助。其他 IDE(如 IntelliJ)可能不需要任何额外配置。
Check for the support for code completion on static members.
检查对静态成员代码补全的支持。

(#spring-mvc-test-client-resources)3.8.2. Further Examples of Client-side REST Tests

3.8.2. 客户端 REST 测试的更多示例

Spring MVC Test’s own tests include example tests of client-side REST tests.
Spring MVC Test 自带的测试包括客户端 REST 测试的示例测试。