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
This commit is contained in:
Andy Wilkinson
2016-06-28 11:17:37 +01:00
parent 61226b5619
commit 417547e61a
2 changed files with 127 additions and 7 deletions

View File

@@ -16,6 +16,9 @@
package org.springframework.restdocs.restassured;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
@@ -35,6 +38,8 @@ import org.springframework.restdocs.operation.OperationRequestPart;
import org.springframework.restdocs.operation.OperationRequestPartFactory;
import org.springframework.restdocs.operation.Parameters;
import org.springframework.restdocs.operation.RequestConverter;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StreamUtils;
/**
* A converter for creating an {@link OperationRequest} from a REST Assured
@@ -64,6 +69,12 @@ class RestAssuredRequestConverter
else if (content instanceof byte[]) {
return (byte[]) content;
}
else if (content instanceof File) {
return copyToByteArray((File) content);
}
else if (content instanceof InputStream) {
return copyToByteArray((InputStream) content);
}
else if (content == null) {
return new byte[0];
}
@@ -73,6 +84,33 @@ class RestAssuredRequestConverter
}
}
private byte[] copyToByteArray(File file) {
try {
return FileCopyUtils.copyToByteArray(file);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to read content from file " + file,
ex);
}
}
private byte[] copyToByteArray(InputStream inputStream) {
try {
inputStream.reset();
}
catch (IOException ex) {
throw new IllegalStateException("Cannot read content from input stream "
+ inputStream + " due to reset() failure");
}
try {
return StreamUtils.copyToByteArray(inputStream);
}
catch (IOException ex) {
throw new IllegalStateException(
"Failed to read content from input stream " + inputStream, ex);
}
}
private HttpHeaders extractHeaders(FilterableRequestSpecification requestSpec) {
HttpHeaders httpHeaders = new HttpHeaders();
for (Header header : requestSpec.getHeaders()) {

View File

@@ -18,6 +18,8 @@ package org.springframework.restdocs.restassured;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
@@ -198,25 +200,105 @@ public class RestAssuredRequestConverterTests {
}
@Test
public void inputStreamBodyIsNotSupported() {
public void byteArrayInputStreamBody() {
RequestSpecification requestSpec = RestAssured.given()
.body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 }))
.port(this.port);
requestSpec.post();
this.thrown.expectMessage(
equalTo("Unsupported request content: java.io.ByteArrayInputStream"));
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getContent(), is(equalTo(new byte[] { 1, 2, 3, 4 })));
}
@Test
public void fileBody() {
RequestSpecification requestSpec = RestAssured.given()
.body(new File("src/test/resources/body.txt")).port(this.port);
requestSpec.post();
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getContentAsString(), is(equalTo("file")));
}
@Test
public void fileInputStreamBody() throws FileNotFoundException {
FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt");
RequestSpecification requestSpec = RestAssured.given().body(inputStream)
.port(this.port);
requestSpec.post();
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Cannot read content from input stream " + inputStream
+ " due to reset() failure");
this.factory.convert((FilterableRequestSpecification) requestSpec);
}
@Test
public void fileBodyIsNotSupported() {
RequestSpecification requestSpec = RestAssured.given()
.body(new File("src/test/resources/body.txt")).port(this.port);
public void multipartWithByteArrayInputStreamBody() {
RequestSpecification requestSpec = RestAssured.given().port(this.port)
.multiPart("foo", "foo.txt", new ByteArrayInputStream("foo".getBytes()));
requestSpec.post();
this.thrown.expectMessage(equalTo("Unsupported request content: java.io.File"));
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getParts().iterator().next().getContentAsString(),
is(equalTo("foo")));
}
@Test
public void multipartWithStringBody() {
RequestSpecification requestSpec = RestAssured.given().port(this.port)
.multiPart("control", "foo");
requestSpec.post();
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getParts().iterator().next().getContentAsString(),
is(equalTo("foo")));
}
@Test
public void multipartWithByteArrayBody() {
RequestSpecification requestSpec = RestAssured.given().port(this.port)
.multiPart("control", "file", "foo".getBytes());
requestSpec.post();
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getParts().iterator().next().getContentAsString(),
is(equalTo("foo")));
}
@Test
public void multipartWithFileBody() {
RequestSpecification requestSpec = RestAssured.given().port(this.port)
.multiPart(new File("src/test/resources/body.txt"));
requestSpec.post();
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getParts().iterator().next().getContentAsString(),
is(equalTo("file")));
}
@Test
public void multipartWithFileInputStreamBody() throws FileNotFoundException {
FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt");
RequestSpecification requestSpec = RestAssured.given().port(this.port)
.multiPart("foo", "foo.txt", inputStream);
requestSpec.post();
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Cannot read content from input stream " + inputStream
+ " due to reset() failure");
this.factory.convert((FilterableRequestSpecification) requestSpec);
}
@Test
public void multipartWithObjectBody() {
RequestSpecification requestSpec = RestAssured.given().port(this.port)
.multiPart("control", new ObjectBody("bar"));
requestSpec.post();
OperationRequest request = this.factory
.convert((FilterableRequestSpecification) requestSpec);
assertThat(request.getParts().iterator().next().getContentAsString(),
is(equalTo("{\"foo\":\"bar\"}")));
}
/**
* Minimal test web application.
*/