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());