Skip to content

Latest commit

 

History

History
136 lines (108 loc) · 5.63 KB

spring-mvc-test-client.adoc

File metadata and controls

136 lines (108 loc) · 5.63 KB

Testing Client Applications

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:

Java
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();
Kotlin
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.

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:

Java
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
Kotlin
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:

Java
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();
Kotlin
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.

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:

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

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

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

Static Imports

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. Check for the support for code completion on static members.

Further Examples of Client-side REST Tests

Spring MVC Test’s own tests include {spring-framework-main-code}/spring-test/src/test/java/org/springframework/test/web/client/samples[example tests] of client-side REST tests.