Skip to content

Commit 417547e

Browse files
committed
Support more types of content in RestAssuredRequestConverter
Previously, RestAssuredRequestConverter only supported request and request part content that was null, a String or a byte[]. This was particularly problematic for multipart requests as RestAssured performs some internal conversion which meant that, no matter what the when a byte[] was provided it was wrapped in a ByteArrayInputStream meaning that the converter could not read it. The commit improves RestAssuredRequestConverter so that it will now convert File content and InputStream content where the stream supported reset(). Closes gh-252
1 parent 61226b5 commit 417547e

File tree

2 files changed

+126
-6
lines changed

2 files changed

+126
-6
lines changed

spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package org.springframework.restdocs.restassured;
1818

19+
import java.io.File;
20+
import java.io.IOException;
21+
import java.io.InputStream;
1922
import java.net.URI;
2023
import java.util.ArrayList;
2124
import java.util.Collection;
@@ -35,6 +38,8 @@
3538
import org.springframework.restdocs.operation.OperationRequestPartFactory;
3639
import org.springframework.restdocs.operation.Parameters;
3740
import org.springframework.restdocs.operation.RequestConverter;
41+
import org.springframework.util.FileCopyUtils;
42+
import org.springframework.util.StreamUtils;
3843

3944
/**
4045
* A converter for creating an {@link OperationRequest} from a REST Assured
@@ -64,6 +69,12 @@ private byte[] convertContent(Object content) {
6469
else if (content instanceof byte[]) {
6570
return (byte[]) content;
6671
}
72+
else if (content instanceof File) {
73+
return copyToByteArray((File) content);
74+
}
75+
else if (content instanceof InputStream) {
76+
return copyToByteArray((InputStream) content);
77+
}
6778
else if (content == null) {
6879
return new byte[0];
6980
}
@@ -73,6 +84,33 @@ else if (content == null) {
7384
}
7485
}
7586

87+
private byte[] copyToByteArray(File file) {
88+
try {
89+
return FileCopyUtils.copyToByteArray(file);
90+
}
91+
catch (IOException ex) {
92+
throw new IllegalStateException("Failed to read content from file " + file,
93+
ex);
94+
}
95+
}
96+
97+
private byte[] copyToByteArray(InputStream inputStream) {
98+
try {
99+
inputStream.reset();
100+
}
101+
catch (IOException ex) {
102+
throw new IllegalStateException("Cannot read content from input stream "
103+
+ inputStream + " due to reset() failure");
104+
}
105+
try {
106+
return StreamUtils.copyToByteArray(inputStream);
107+
}
108+
catch (IOException ex) {
109+
throw new IllegalStateException(
110+
"Failed to read content from input stream " + inputStream, ex);
111+
}
112+
}
113+
76114
private HttpHeaders extractHeaders(FilterableRequestSpecification requestSpec) {
77115
HttpHeaders httpHeaders = new HttpHeaders();
78116
for (Header header : requestSpec.getHeaders()) {

spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.io.ByteArrayInputStream;
2020
import java.io.File;
21+
import java.io.FileInputStream;
22+
import java.io.FileNotFoundException;
2123
import java.net.URI;
2224
import java.util.Arrays;
2325
import java.util.Collection;
@@ -198,25 +200,105 @@ public void objectBody() {
198200
}
199201

200202
@Test
201-
public void inputStreamBodyIsNotSupported() {
203+
public void byteArrayInputStreamBody() {
202204
RequestSpecification requestSpec = RestAssured.given()
203205
.body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 }))
204206
.port(this.port);
205207
requestSpec.post();
206-
this.thrown.expectMessage(
207-
equalTo("Unsupported request content: java.io.ByteArrayInputStream"));
208-
this.factory.convert((FilterableRequestSpecification) requestSpec);
208+
OperationRequest request = this.factory
209+
.convert((FilterableRequestSpecification) requestSpec);
210+
assertThat(request.getContent(), is(equalTo(new byte[] { 1, 2, 3, 4 })));
209211
}
210212

211213
@Test
212-
public void fileBodyIsNotSupported() {
214+
public void fileBody() {
213215
RequestSpecification requestSpec = RestAssured.given()
214216
.body(new File("src/test/resources/body.txt")).port(this.port);
215217
requestSpec.post();
216-
this.thrown.expectMessage(equalTo("Unsupported request content: java.io.File"));
218+
OperationRequest request = this.factory
219+
.convert((FilterableRequestSpecification) requestSpec);
220+
assertThat(request.getContentAsString(), is(equalTo("file")));
221+
}
222+
223+
@Test
224+
public void fileInputStreamBody() throws FileNotFoundException {
225+
FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt");
226+
RequestSpecification requestSpec = RestAssured.given().body(inputStream)
227+
.port(this.port);
228+
requestSpec.post();
229+
this.thrown.expect(IllegalStateException.class);
230+
this.thrown.expectMessage("Cannot read content from input stream " + inputStream
231+
+ " due to reset() failure");
217232
this.factory.convert((FilterableRequestSpecification) requestSpec);
218233
}
219234

235+
@Test
236+
public void multipartWithByteArrayInputStreamBody() {
237+
RequestSpecification requestSpec = RestAssured.given().port(this.port)
238+
.multiPart("foo", "foo.txt", new ByteArrayInputStream("foo".getBytes()));
239+
requestSpec.post();
240+
OperationRequest request = this.factory
241+
.convert((FilterableRequestSpecification) requestSpec);
242+
assertThat(request.getParts().iterator().next().getContentAsString(),
243+
is(equalTo("foo")));
244+
}
245+
246+
@Test
247+
public void multipartWithStringBody() {
248+
RequestSpecification requestSpec = RestAssured.given().port(this.port)
249+
.multiPart("control", "foo");
250+
requestSpec.post();
251+
OperationRequest request = this.factory
252+
.convert((FilterableRequestSpecification) requestSpec);
253+
assertThat(request.getParts().iterator().next().getContentAsString(),
254+
is(equalTo("foo")));
255+
}
256+
257+
@Test
258+
public void multipartWithByteArrayBody() {
259+
RequestSpecification requestSpec = RestAssured.given().port(this.port)
260+
.multiPart("control", "file", "foo".getBytes());
261+
requestSpec.post();
262+
OperationRequest request = this.factory
263+
.convert((FilterableRequestSpecification) requestSpec);
264+
assertThat(request.getParts().iterator().next().getContentAsString(),
265+
is(equalTo("foo")));
266+
}
267+
268+
@Test
269+
public void multipartWithFileBody() {
270+
RequestSpecification requestSpec = RestAssured.given().port(this.port)
271+
.multiPart(new File("src/test/resources/body.txt"));
272+
requestSpec.post();
273+
OperationRequest request = this.factory
274+
.convert((FilterableRequestSpecification) requestSpec);
275+
assertThat(request.getParts().iterator().next().getContentAsString(),
276+
is(equalTo("file")));
277+
}
278+
279+
@Test
280+
public void multipartWithFileInputStreamBody() throws FileNotFoundException {
281+
FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt");
282+
RequestSpecification requestSpec = RestAssured.given().port(this.port)
283+
.multiPart("foo", "foo.txt", inputStream);
284+
requestSpec.post();
285+
this.thrown.expect(IllegalStateException.class);
286+
this.thrown.expectMessage("Cannot read content from input stream " + inputStream
287+
+ " due to reset() failure");
288+
this.factory.convert((FilterableRequestSpecification) requestSpec);
289+
}
290+
291+
@Test
292+
public void multipartWithObjectBody() {
293+
RequestSpecification requestSpec = RestAssured.given().port(this.port)
294+
.multiPart("control", new ObjectBody("bar"));
295+
requestSpec.post();
296+
OperationRequest request = this.factory
297+
.convert((FilterableRequestSpecification) requestSpec);
298+
assertThat(request.getParts().iterator().next().getContentAsString(),
299+
is(equalTo("{\"foo\":\"bar\"}")));
300+
}
301+
220302
/**
221303
* Minimal test web application.
222304
*/

0 commit comments

Comments
 (0)