Wiremock:如何模拟返回InputStream的端点?

huangapple go评论110阅读模式
英文:

Wiremock: how to mock endpoint that returns InputStream?

问题

以下是翻译好的内容:

我有一个可以请求端点并读取其响应的工作代码(流是一个PDF):

  1. private Response readResponseBody(Response response) throws IOException {
  2. InputStream inputStream = response.readEntity(InputStream.class);
  3. try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
  4. if (inputStream != null) {
  5. byte[] buffer = new byte[1024];
  6. int len;
  7. while ((len = inputStream.read(buffer)) != -1) { // 在这一行出现了与Wiremock相关的错误
  8. os.write(buffer, 0, len);
  9. }
  10. }
  11. }
  12. // 其他操作...
  13. }

我尝试在测试环境中使用 JUnit4 的 @Rule 来使用 Wiremock 模拟该端点,方法如下:

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

但是当我请求模拟的端点时,我无法读取 InputStream,在上面引用的代码行中出现以下错误:

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

那么,使用 Wiremock 如何正确模拟返回 InputStream 的端点呢?

英文:

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

  1. private Response readResponseBody(Response response) throws IOException {
  2. InputStream inputStream = response.readEntity(InputStream.class);
  3. try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
  4. if (inputStream != null) {
  5. byte[] buffer = new byte[1024];
  6. int len;
  7. while ((len = inputStream.read(buffer)) != -1) { //error this line with wiremock
  8. os.write(buffer, 0, len);
  9. }
  10. }
  11. }
  12. //other stuffs...
  13. }

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

  1. byte[] pdfFile = Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("file.pdf").toURI()));
  2. stubFor(
  3. get(urlPathMatching(mockPath))
  4. .withHeader("Authorization", equalTo(mockedToken))
  5. .willReturn(aResponse()
  6. .withStatus(200)
  7. .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:

  1. 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?

答案1

得分: 1

在花了一些时间阅读 Wiremock 文档后,我找到了问题出在哪里。创建一个下载某个文件的存根的一种方法是将该文件放在 src/test/resources/__files 目录下,如果我要使用这种方法:

  1. withBodyFile("file.pdf")

默认情况下,这是 Wiremock 服务器寻找要通过存根进行 下载 的任何文件的目录。这解决了我的问题。

英文:

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:

  1. 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.

答案2

得分: 0

基于这个回答,我猜想你可以将文件路径作为响应主体返回。

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

如果这样不起作用,我建议在响应中添加一个内容类型标头。假设文件是PDF格式,可以这样做:

  1. .withHeader("Content-Type", "application/pdf")
英文:

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

  1. .willReturn(aResponse()
  2. .withStatus(200)
  3. .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

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

huangapple
  • 本文由 发表于 2020年10月19日 23:37:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64430621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定