Browse Source

Add bufferContent option to MockRestServiceServer

Issue: SPR-14694
pull/1744/head
Rossen Stoyanchev 7 years ago
parent
commit
541ee13934
  1. 25
      spring-test/src/main/java/org/springframework/test/web/client/MockRestServiceServer.java
  2. 64
      spring-test/src/test/java/org/springframework/test/web/client/samples/SampleTests.java

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,6 +20,7 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
@ -201,6 +202,14 @@ public class MockRestServiceServer {
*/ */
MockRestServiceServerBuilder ignoreExpectOrder(boolean ignoreExpectOrder); MockRestServiceServerBuilder ignoreExpectOrder(boolean ignoreExpectOrder);
/**
* Use the {@link BufferingClientHttpRequestFactory} wrapper to buffer
* the input and output streams, and for example, allow multiple reads
* of the response body.
* @since 5.0.5
*/
MockRestServiceServerBuilder bufferContent();
/** /**
* Build the {@code MockRestServiceServer} and set up the underlying * Build the {@code MockRestServiceServer} and set up the underlying
* {@code RestTemplate} or {@code AsyncRestTemplate} with a * {@code RestTemplate} or {@code AsyncRestTemplate} with a
@ -226,6 +235,9 @@ public class MockRestServiceServer {
private boolean ignoreExpectOrder; private boolean ignoreExpectOrder;
private boolean bufferContent;
public DefaultBuilder(RestTemplate restTemplate) { public DefaultBuilder(RestTemplate restTemplate) {
Assert.notNull(restTemplate, "RestTemplate must not be null"); Assert.notNull(restTemplate, "RestTemplate must not be null");
this.restTemplate = restTemplate; this.restTemplate = restTemplate;
@ -244,6 +256,12 @@ public class MockRestServiceServer {
return this; return this;
} }
@Override
public MockRestServiceServerBuilder bufferContent() {
this.bufferContent = true;
return this;
}
@Override @Override
public MockRestServiceServer build() { public MockRestServiceServer build() {
if (this.ignoreExpectOrder) { if (this.ignoreExpectOrder) {
@ -259,8 +277,13 @@ public class MockRestServiceServer {
MockRestServiceServer server = new MockRestServiceServer(manager); MockRestServiceServer server = new MockRestServiceServer(manager);
MockClientHttpRequestFactory factory = server.new MockClientHttpRequestFactory(); MockClientHttpRequestFactory factory = server.new MockClientHttpRequestFactory();
if (this.restTemplate != null) { if (this.restTemplate != null) {
if (this.bufferContent) {
this.restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
}
else {
this.restTemplate.setRequestFactory(factory); this.restTemplate.setRequestFactory(factory);
} }
}
if (this.asyncRestTemplate != null) { if (this.asyncRestTemplate != null) {
this.asyncRestTemplate.setAsyncRequestFactory(factory); this.asyncRestTemplate.setAsyncRequestFactory(factory);
} }

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

@ -15,18 +15,26 @@
*/ */
package org.springframework.test.web.client.samples; package org.springframework.test.web.client.samples;
import java.io.IOException;
import java.util.Collections;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.test.web.Person; import org.springframework.test.web.Person;
import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.*;
import static org.springframework.test.web.client.ExpectedCount.manyTimes; import static org.springframework.test.web.client.ExpectedCount.manyTimes;
import static org.springframework.test.web.client.ExpectedCount.never; import static org.springframework.test.web.client.ExpectedCount.never;
import static org.springframework.test.web.client.ExpectedCount.once; import static org.springframework.test.web.client.ExpectedCount.once;
@ -55,7 +63,7 @@ public class SampleTests {
} }
@Test @Test
public void performGet() throws Exception { public void performGet() {
String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}"; String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}";
@ -73,7 +81,7 @@ public class SampleTests {
} }
@Test @Test
public void performGetManyTimes() throws Exception { public void performGetManyTimes() {
String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}"; String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}";
@ -95,7 +103,7 @@ public class SampleTests {
} }
@Test @Test
public void expectNever() throws Exception { public void expectNever() {
String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}"; String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}";
@ -110,7 +118,7 @@ public class SampleTests {
} }
@Test(expected = AssertionError.class) @Test(expected = AssertionError.class)
public void expectNeverViolated() throws Exception { public void expectNeverViolated() {
String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}"; String responseBody = "{\"name\" : \"Ludwig van Beethoven\", \"someDouble\" : \"1.6035\"}";
@ -124,7 +132,7 @@ public class SampleTests {
} }
@Test @Test
public void performGetWithResponseBodyFromFile() throws Exception { public void performGetWithResponseBodyFromFile() {
Resource responseBody = new ClassPathResource("ludwig.json", this.getClass()); Resource responseBody = new ClassPathResource("ludwig.json", this.getClass());
@ -170,4 +178,48 @@ public class SampleTests {
assertTrue(error.getMessage(), error.getMessage().contains("2 unsatisfied expectation(s)")); assertTrue(error.getMessage(), error.getMessage().contains("2 unsatisfied expectation(s)"));
} }
} }
@Test // SPR-14694
public void repeatedAccessToResponseViaResource() {
Resource resource = new ClassPathResource("ludwig.json", this.getClass());
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(new ContentInterceptor(resource)));
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate)
.ignoreExpectOrder(true)
.bufferContent() // enable repeated reads of response body
.build();
mockServer.expect(requestTo("/composers/42")).andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(resource, MediaType.APPLICATION_JSON));
restTemplate.getForObject("/composers/{id}", Person.class, 42);
mockServer.verify();
}
private static class ContentInterceptor implements ClientHttpRequestInterceptor {
private final Resource resource;
private ContentInterceptor(Resource resource) {
this.resource = resource;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
ClientHttpResponse response = execution.execute(request, body);
byte[] expected = FileCopyUtils.copyToByteArray(this.resource.getInputStream());
byte[] actual = FileCopyUtils.copyToByteArray(response.getBody());
assertEquals(new String(expected), new String(actual));
return response;
}
}
} }

Loading…
Cancel
Save