Skip to content

Commit 4da4f2b

Browse files
committed
Async support in MockMvcClientHttpRequestFactory
Issue: SPR-15181
1 parent f5fe3f0 commit 4da4f2b

File tree

2 files changed

+64
-30
lines changed

2 files changed

+64
-30
lines changed

spring-test/src/main/java/org/springframework/test/web/client/MockMvcClientHttpRequestFactory.java

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,19 +31,26 @@
3131
import org.springframework.mock.http.client.MockClientHttpResponse;
3232
import org.springframework.mock.web.MockHttpServletResponse;
3333
import org.springframework.test.web.servlet.MockMvc;
34-
import org.springframework.test.web.servlet.MvcResult;
35-
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
3634
import org.springframework.util.Assert;
3735

38-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
36+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request;
37+
3938

4039
/**
4140
* A {@link ClientHttpRequestFactory} for requests executed via {@link MockMvc}.
4241
*
42+
* <p>As of 5.0 this class also implements
43+
* {@link org.springframework.http.client.AsyncClientHttpRequestFactory
44+
* AsyncClientHttpRequestFactory}. However note that
45+
* {@link org.springframework.web.client.AsyncRestTemplate} and related classes
46+
* have been deprecated at the same time.
47+
*
4348
* @author Rossen Stoyanchev
4449
* @since 3.2
4550
*/
46-
public class MockMvcClientHttpRequestFactory implements ClientHttpRequestFactory {
51+
@SuppressWarnings("deprecation")
52+
public class MockMvcClientHttpRequestFactory
53+
implements ClientHttpRequestFactory, org.springframework.http.client.AsyncClientHttpRequestFactory {
4754

4855
private final MockMvc mockMvc;
4956

@@ -55,31 +62,46 @@ public MockMvcClientHttpRequestFactory(MockMvc mockMvc) {
5562

5663

5764
@Override
58-
public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) throws IOException {
65+
public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) {
5966
return new MockClientHttpRequest(httpMethod, uri) {
6067
@Override
6168
public ClientHttpResponse executeInternal() throws IOException {
62-
try {
63-
MockHttpServletRequestBuilder requestBuilder = request(httpMethod, uri);
64-
requestBuilder.content(getBodyAsBytes());
65-
requestBuilder.headers(getHeaders());
66-
MvcResult mvcResult = MockMvcClientHttpRequestFactory.this.mockMvc.perform(requestBuilder).andReturn();
67-
MockHttpServletResponse servletResponse = mvcResult.getResponse();
68-
HttpStatus status = HttpStatus.valueOf(servletResponse.getStatus());
69-
byte[] body = servletResponse.getContentAsByteArray();
70-
HttpHeaders headers = getResponseHeaders(servletResponse);
71-
MockClientHttpResponse clientResponse = new MockClientHttpResponse(body, status);
72-
clientResponse.getHeaders().putAll(headers);
73-
return clientResponse;
74-
}
75-
catch (Exception ex) {
76-
byte[] body = ex.toString().getBytes(StandardCharsets.UTF_8);
77-
return new MockClientHttpResponse(body, HttpStatus.INTERNAL_SERVER_ERROR);
78-
}
69+
return getClientHttpResponse(httpMethod, uri, getHeaders(), getBodyAsBytes());
70+
}
71+
};
72+
}
73+
74+
@Override
75+
public org.springframework.http.client.AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod method) {
76+
return new org.springframework.mock.http.client.MockAsyncClientHttpRequest(method, uri) {
77+
@Override
78+
protected ClientHttpResponse executeInternal() throws IOException {
79+
return getClientHttpResponse(method, uri, getHeaders(), getBodyAsBytes());
7980
}
8081
};
8182
}
8283

84+
private ClientHttpResponse getClientHttpResponse(
85+
HttpMethod httpMethod, URI uri, HttpHeaders requestHeaders, byte[] requestBody) {
86+
87+
try {
88+
MockHttpServletResponse servletResponse = mockMvc
89+
.perform(request(httpMethod, uri).content(requestBody).headers(requestHeaders))
90+
.andReturn()
91+
.getResponse();
92+
93+
HttpStatus status = HttpStatus.valueOf(servletResponse.getStatus());
94+
byte[] body = servletResponse.getContentAsByteArray();
95+
MockClientHttpResponse clientResponse = new MockClientHttpResponse(body, status);
96+
clientResponse.getHeaders().putAll(getResponseHeaders(servletResponse));
97+
return clientResponse;
98+
}
99+
catch (Exception ex) {
100+
byte[] body = ex.toString().getBytes(StandardCharsets.UTF_8);
101+
return new MockClientHttpResponse(body, HttpStatus.INTERNAL_SERVER_ERROR);
102+
}
103+
}
104+
83105
private HttpHeaders getResponseHeaders(MockHttpServletResponse response) {
84106
HttpHeaders headers = new HttpHeaders();
85107
for (String name : response.getHeaderNames()) {

spring-test/src/test/java/org/springframework/test/web/client/samples/MockMvcClientHttpRequestFactoryTests.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,23 +23,27 @@
2323
import org.springframework.beans.factory.annotation.Autowired;
2424
import org.springframework.context.annotation.ComponentScan;
2525
import org.springframework.context.annotation.Configuration;
26+
import org.springframework.http.ResponseEntity;
2627
import org.springframework.stereotype.Controller;
2728
import org.springframework.test.context.ContextConfiguration;
2829
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
2930
import org.springframework.test.context.web.WebAppConfiguration;
3031
import org.springframework.test.web.client.MockMvcClientHttpRequestFactory;
3132
import org.springframework.test.web.servlet.MockMvc;
3233
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
34+
import org.springframework.util.concurrent.ListenableFuture;
3335
import org.springframework.web.bind.annotation.RequestMapping;
3436
import org.springframework.web.bind.annotation.RequestMethod;
3537
import org.springframework.web.bind.annotation.ResponseBody;
38+
import org.springframework.web.client.AsyncRestTemplate;
3639
import org.springframework.web.client.RestTemplate;
3740
import org.springframework.web.context.WebApplicationContext;
3841
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
3942
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
4043

41-
import static org.junit.Assert.*;
42-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
44+
import static org.junit.Assert.assertEquals;
45+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
46+
4347

4448
/**
4549
* Tests that use a {@link RestTemplate} configured with a
@@ -57,21 +61,29 @@ public class MockMvcClientHttpRequestFactoryTests {
5761
@Autowired
5862
private WebApplicationContext wac;
5963

60-
private RestTemplate restTemplate;
64+
private MockMvc mockMvc;
6165

6266

6367
@Before
6468
public void setup() {
65-
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();
66-
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));
69+
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build();
6770
}
6871

6972
@Test
7073
public void test() throws Exception {
71-
String result = this.restTemplate.getForObject("/foo", String.class);
74+
RestTemplate template = new RestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc));
75+
String result = template.getForObject("/foo", String.class);
7276
assertEquals("bar", result);
7377
}
7478

79+
@Test
80+
@SuppressWarnings("deprecation")
81+
public void testAsyncTemplate() throws Exception {
82+
AsyncRestTemplate template = new AsyncRestTemplate(new MockMvcClientHttpRequestFactory(this.mockMvc));
83+
ListenableFuture<ResponseEntity<String>> entity = template.getForEntity("/foo", String.class);
84+
assertEquals("bar", entity.get().getBody());
85+
}
86+
7587

7688
@EnableWebMvc
7789
@Configuration

0 commit comments

Comments
 (0)