WireMock: How to mock file download process?
Asked Answered
S

3

7

I'm new inWireMock. I am running the WireMock server as a standalone process. I am able to mock simple rest api, by configuring json files under /mappings folder. Now, I want to mock a file downloading end point. How can I do that?

I don't know if it helps, the end point is in Java/Spring, which looks like this:

@RequestMapping(value = "xxx/get", method = {RequestMethod.GET})
public ResponseEntity<Object> getFile(HttpServletResponse response) throws Exception {

    final Resource fileResource = fileResourceFactoryBean.getObject();

    if (fileResource.exists()) {
        try (InputStream inputStream = fileResource.getInputStream()) {
            IOUtils.copy(inputStream, response.getOutputStream());

            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileResource.getFilename());

            response.flushBuffer();
            inputStream.close();

            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            LOGGER.error("Error reading file: ", e);
            return new ResponseEntity<Object>("Error reading file.", HttpStatus.BAD_REQUEST);
        }
    }

    return new ResponseEntity<Object>(fileResource.getFilename() + " not found.", HttpStatus.BAD_REQUEST);
}

My response section in the mappings json file looks like this:

"response": {
    "status": 200,
    "bodyFileName": "fileName", // file under __files directory
    "headers": {
      "Content-Type": "application/octet-stream"
    }
  }
Segno answered 22/5, 2017 at 18:24 Comment(0)
B
6

A very late answer, but the only working solution I found is this:

"response": {
            "status": 200,
            "headers": {
                "Content-Type": "image/jpeg"
            },
            "base64Body": "2wBDAAQDAwQDAwQE...=="       
        }

Where I put the image content, encoded in Base64, directly in the mapping file.

More or less ok...for small files.

In java, it seems a bit more handy :

.willReturn( aResponse()
     .withBody( myImage.getBytes() )

Using the json DSL, you only have:

  • bodyFileName (NB: the doc says: "body files are expected to be in UTF-8 format")
  • base64Body
  • but something like base64BodyFileName is NOT possible :-(
Balladist answered 19/1, 2021 at 9:55 Comment(0)
U
3

File downloads are really no different than sending markup or JSON. Web browsers treat a file as a download if they don't recognise the MIME type as one it can render.

To make this happen with WireMock, try:

  • Setting the Content-Type header on the response to application/octet-stream
  • Setting the response to use a body file (the one you wish to download)
Unsought answered 23/5, 2017 at 7:24 Comment(7)
I have updated my question with the response content I am using. It matches what you're suggesting. But it's not working for me. Do you see anything wrong with that piece of response content? Could you please take a took? Thanks Tom.Segno
Can you describe what you're trying to do in a bit more detail? How are you testing the stub? With a web browser, or programmatic client? What is the failure you're seeing?Unsought
Actually, my client is a cordova android app that makes a server call to download a (database) file. I'm using WireMock to mock the web app. The error says: Matched response definition: (no response definition configured)Segno
OK, that means it's the request part that isn't correct. I suggest checking the URL, method and request headers you've specified match what the app is sending. Update your original post with details if you can't see anything obviously wrong.Unsought
WireMock is receiving the request per console message. The client is getting 404 error. The console log from WireMock says the following: Response: HTTP/1.1 404 (no headers)Segno
So WireMock isn't matching the request. If you post the full details of your stub mapping and the request that's being made I might be able to help figure out why.Unsought
You could also try the c# dotnet version : github.com/WireMock-Net/WireMock.NetEponymous
M
3

I use mapping like:

{
  "request": {
    "method": "GET",
    "url": "/files/b8b6461d-75c7-4908-a418-777140912059"
  },
  "response": {
    "status": 200,
    "bodyFileName": "file.pdf",
    "headers": {
      "Content-Type": "application/pdf",
      "Content-Disposition": "attachment;filename=\"file.pdf\""
    }
  }
}

file.pdf is actual file in __files directory. It works as expected for client using this stub.

Menstrual answered 30/12, 2022 at 9:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.