Rafael A P Nascimento
Rafael A P Nascimento

Reputation: 475

Wiremock: how to mock endpoint that returns InputStream?

I have a working code that requests an endpoint and read its response this way (the stream is a PDF):

private Response readResponseBody(Response response) throws IOException {
  InputStream inputStream = response.readEntity(InputStream.class);
  try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
    if (inputStream != null) {
      byte[] buffer = new byte[1024];
      int len;
      while ((len = inputStream.read(buffer)) != -1) { //error this line with wiremock
        os.write(buffer, 0, len);
      }
    }
  }
  //other stuffs...
}

I tried to mock that enpoint using wiremock at test environment using JUnit4 @Rule, this way:

byte[] pdfFile = Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("file.pdf").toURI()));
stubFor(
  get(urlPathMatching(mockPath))
  .withHeader("Authorization", equalTo(mockedToken))
  .willReturn(aResponse()
    .withStatus(200)
    .withBody(pdfFile)));

But when I request the mocked endpoint, I'm not able to read the InputStream, I get this error at the referred line above:

org.apache.http.ConnectionClosedException: Premature end of chunk coded message body: closing chunk expected

Which is the right way to mock an endpoint that returns an InputStream using Wiremock?

Upvotes: 1

Views: 5690

Answers (2)

Rafael A P Nascimento
Rafael A P Nascimento

Reputation: 475

After spending some time reading Wiremock documentation, I figured out what's wrong. One way to create a stub that downloads some file is to put that file under src/test/resources/__files directory, if I'm going to use the method:

withBodyFile("file.pdf")

By default, this is the directory where Wiremock server will look to get any file to be downloaded through the stubs. This solved my problem.

Upvotes: 1

agoff
agoff

Reputation: 7125

Based on this response, I would guess that you can just return the file path as the response body.

  .willReturn(aResponse()
    .withStatus(200)
    .withBodyFile("/path/to/pdf/file")));

If that does not work, I would suggest adding a content-type header to the response. Assuming the file is a pdf, that would be

.withHeader("Content-Type", "application/pdf")

Upvotes: 0

Related Questions