Home > OS >  How do I verify my image download when it is returned as a Spring Resource?
How do I verify my image download when it is returned as a Spring Resource?

Time:12-19

I'm using Spring WebMvc 5.3 (along with the spring-test module of the same version). The mockito version I'm using is 3.6. I have a controller method in which I download an image file ...

import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;

...
  @Override
  public ResponseEntity<Resource> download(Long imgd)
    ...
    InputStream result =
        myService.getImageFile(imgId);
    ...
    
    Resource resource = new InputStreamResource(result);
    HttpHeaders responseHeaders = new HttpHeaders();
    ...

    return ResponseEntity.ok().headers(responseHeaders).body(resource);

In my unit test, I would like to verify a successul result, so I have

  MockMvc mockMvc;

  @Test
  void testDownloadImg() {

    File imageFile = new File("src/test/resources", "test.png");
    InputStream inputStream = new FileInputStream(imageFile);
    byte[] imgAsBytes = new byte[inputStream.available()];
    inputStream.read(imgAsBytes);

    ...
    when(myMockImgService.getImageFile(id)).thenReturn(inputStream);
    byte[] expectedContent = Files.readAllBytes(imageFile.toPath());
    mockMvc
        .perform(
            get(DOWNLOAD_URL)
                .contentType(MediaType.APPLICATION_JSON))
        .andExpect(content().bytes(imgAsBytes)
        .andExpect(status().isOk())

Unfortunately, this always fails because the content (content().bytes()) that comes back from my method is always "{}". When I run my controller method live, the image is returned just fine, so it would seem the only issue here is writing a test case to verify it. Because I use a code generation tool, I must maintain the contract of returning a ResponseEntity.

CodePudding user response:

The problem is that you read out all of your input stream into imgAsBytes before returning it as a mock response. This results in an empty stream being returned. To fix that you can use the expectedContent you already have for assertion:

        File imageFile = new File("src/test/resources", "test.png");
        InputStream inputStream = new FileInputStream(imageFile);
//        byte[] imgAsBytes = new byte[inputStream.available()];
//        inputStream.read(imgAsBytes);

        when(mainService.getImageFile(any())).thenReturn(inputStream);

        byte[] expectedContent = Files.readAllBytes(imageFile.toPath());
        mockMvc
                .perform(
                        get("/download").contentType(MediaType.APPLICATION_JSON))
                .andExpect(content().bytes(expectedContent))
                .andExpect(status().isOk());
  • Related