在我的生产代码中,我需要对一个控制器执行POST命令,该控制器响应StreamingResponseBody。此类代码的一个简短示例是:
@RestController
@RequestMapping("/api")
public class DalaLakeRealController {
@PostMapping(value = "/downloaddbcsv", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<StreamingResponseBody> downloadDBcsv(@Valid @RequestBody SearchQuery searchRequest) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, "application/csv")
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=demoStream.csv")
.body(
get3Lines()
);
}
public StreamingResponseBody get3Lines() {
StreamingResponseBody streamingResponseBody = new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
outputStream.write("LineNumber111111111n".getBytes());
outputStream.write("LineNumber222222222n".getBytes());
outputStream.write("LineNumber333333333n".getBytes());
}
};
return streamingResponseBody;
}
}
在测试中,我想模拟这个控制器的响应。我已经阅读了以下链接:使用MockRestServiceServer测试REST客户端以模拟外部控制器。
但在mockServer的andRespond中,它期望ClientHttpResponse或ResponseCreator
mockServer.expect(once(), requestTo("http://localhost:8080/api/downloaddbcsv"))
.andRespond(withSuccess("{message : 'under construction'}", MediaType.APPLICATION_JSON));
如何在MockRestServiceServer中使用StreamingResponseBody进行响应?
我希望这能指导你。。。
@Test
public void whenTopicNotExistsThenTopicNotFound() throws IOException, NakadiException {
when(eventTypeRepository.findByName(TEST_EVENT_TYPE_NAME)).thenThrow(NoSuchEventTypeException.class);
final StreamingResponseBody responseBody = createStreamingResponseBody();
final Problem expectedProblem = Problem.valueOf(NOT_FOUND, "topic not found");
assertThat(responseToString(responseBody), TestUtils.JSON_TEST_HELPER.matchesObject(expectedProblem));
}
从以下位置获取上述代码:https://www.programcreek.com/java-api-examples/index.php?api=org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
其思想是将StreamingResponseBody
转换为String
。然后你可以做一些类似的事情:
mockServer.expect(once(), requestTo("http://localhost:8080/api/downloaddbcsv"))
.andRespond(withSuccess(responseToString(responseBody), MediaType.APPLICATION_JSON));
此外,看看这里:https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandlerTests.java
streamingResponseBody()
和responseEntity()
测试方法将响应转换为String
。
尽管这篇文章很旧,但这个答案可能会帮助现在寻找这篇文章的人。
这个问题的答案是下面代码中显示的函数接口(streamingResponseBody(,以及cloudStorageService中下载的模拟返回。
@Test
@WithUserDetailsMock(
email = "participant@localhost",
authorities = AuthoritiesConstants.USER,
cashflowAuthorities = CashflowAuthoritiesConstants.PARTICIPANT
)
void testDownloadFileThenSuccess() throws Exception {
Member loggedMember = memberService.getLoggedMember();
File file = EntityBuilder.file(loggedMember.getGroup()).build(fileRepository::save);
SubmittedPayment submittedPayment = EntityBuilder
.submittedPayment(loggedMember)
.with(SubmittedPayment::setFile, file)
.build(submittedPaymentRepository::save);
String endpoint = String.format("/api/payment/submit/%d/file", submittedPayment.getId());
byte[] fileBytes = "some content".getBytes();
StreamingResponseBody streamingResponseBody = objectStream -> {
var mockInputStream = new ByteArrayInputStream(fileBytes);
try (mockInputStream) {
byte[] bytes = mockInputStream.readAllBytes();
objectStream.write(bytes, 0, bytes.length);
}
};
doReturn(streamingResponseBody).when(cloudStorageService).download(fileArgumentCaptor.capture());
MvcResult response = restTransactionMockMvc.perform(get(endpoint)).andExpect(status().isOk()).andReturn();
assertThat(file).isEqualTo(fileArgumentCaptor.getValue());
assertThat(Arrays.equals(fileBytes, response.getResponse().getContentAsByteArray())).isTrue();
}