【问题标题】:How to create a WSResponse object from string for Play WSClient如何从字符串为 Play WSClient 创建一个 WSResponse 对象
【发布时间】:2016-01-12 20:50:45
【问题描述】:

Documentation 建议使用模拟 Web 服务测试基于 WSClient 的 API 客户端,即创建一个将响应真实 HTTP 请求的play.server.Server

我更喜欢直接从文件创建WSResponse 对象,包括状态行、标题行和正文,而不需要真正的 TCP 连接。这将需要更少的依赖并运行得更快。也可能在其他情况下这很有用。

但我找不到一个简单的方法来做到这一点。 WSResponse 包裹的所有实现似乎都与从网络读取相关联。

我应该为此创建自己的 WSResponse 子类,还是我错了,它已经存在?

【问题讨论】:

  • 你必须使用 Play WSClient 吗?您可以签出 Resitio Mock 框架进行测试。我会建议,开发人员已经创建了所有这个类,将该类作为 .jar 并从中创建模拟服务。
  • @BostonStar 是的,我绑定到 WSClient。我们使用junit+mockito。 Resito 将如何帮助创建 WSResponse 对象?
  • 我认为您可以直接访问原始对象并创建模拟服务。

标签: java testing playframework playframework-2.0 ws-client


【解决方案1】:

Play 的 API 似乎是故意迟钝的。您必须使用他们的“可缓存”类,它们是唯一可以从您周围的对象直接实例化的类。

这应该让你开始:

import play.api.libs.ws.ahc.AhcWSResponse;
import play.api.libs.ws.ahc.cache.CacheableHttpResponseBodyPart;
import play.api.libs.ws.ahc.cache.CacheableHttpResponseHeaders;
import play.api.libs.ws.ahc.cache.CacheableHttpResponseStatus;
import play.shaded.ahc.io.netty.handler.codec.http.DefaultHttpHeaders;
import play.shaded.ahc.org.asynchttpclient.Response;
import play.shaded.ahc.org.asynchttpclient.uri.Uri;

AhcWSResponse response = new AhcWSResponse(new Response.ResponseBuilder()
        .accumulate(new CacheableHttpResponseStatus(Uri.create("uri"), 200, "status text", "protocols!"))
        .accumulate(new CacheableHttpResponseHeaders(false, new DefaultHttpHeaders().add("My-Header", "value")))
        .accumulate(new CacheableHttpResponseBodyPart("my body".getBytes(), true))
        .build());

未记录神秘的布尔值。我的猜测是 BodyPart 的布尔值是否是身体的最后一部分。我对 headers 的猜测是 headers 是否在消息的预告片中。

【讨论】:

  • 感谢您的回复!相当间接的解决方案,但没有更好的内置解决方案,我接受这个。
  • 是的,我还没有正确解析它。神秘的错误消息没有帮助,所以我把它考虑在内,这样我就可以实际测试了。
  • 这对我不起作用。由于某种原因,我找不到CacheableHttpResponseHeaders,使用 Play 2.5
  • 我认为它是 2.6 中的新功能playframework.com/documentation/2.6.0-M4/api/scala/…
【解决方案2】:

我用了另一种方式,用Mockito模拟WSResponse

import play.libs.ws.WSRequest;
import play.libs.ws.WSResponse;
import org.mockito.Mockito;

...

          final WSResponse wsResponseMock = Mockito.mock(WSResponse.class);
          Mockito.doReturn(200).when(wsResponseMock).getStatus();
          final String jsonStr = "{\n"
                  + "  \"response\": {\n"
                  + "    \"route\": [\n"
                  + "      { \"summary\" :\n"
                  + "        {\n"
                  + "          \"distance\": 23\n"
                  + "        }\n"
                  + "      }\n"
                  + "    ]\n"
                  + "  }\n"
                  + "}";
          ObjectMapper mapper = new ObjectMapper();
          JsonNode jsonNode = null;
          try {
            jsonNode = mapper.readTree(jsonStr);
          } catch (IOException e) {
            e.printStackTrace();
          }
          Mockito.doReturn(
                  jsonNode)
              .when(wsResponseMock)
              .asJson();

【讨论】:

  • 您可以使用play.libs.Json#parse(String) 而不是创建对象映射器。此外,建议使用when(..).thenReturn(..) 而不是doReturn(..).when(..)。赞成。
  • 这个解决方案的缺点是需要模拟所有预期的调用,而不是使用外部资源或方便的响应构建 API。
【解决方案3】:

如果你使用play-framework 2.8.xscala,下面的代码可以帮助我们生成一个虚拟的WSResponse

import play.api.libs.ws.ahc.AhcWSResponse
import play.api.libs.ws.ahc.cache.CacheableHttpResponseStatus
import play.shaded.ahc.org.asynchttpclient.Response
import play.shaded.ahc.org.asynchttpclient.uri.Uri
import play.api.libs.ws.ahc.cache.CacheableHttpResponseBodyPart
import play.shaded.ahc.io.netty.handler.codec.http.DefaultHttpHeaders

class OutputWriterSpec extends FlatSpec with Matchers {
  val respBuilder = new Response.ResponseBuilder()
  respBuilder.accumulate(new CacheableHttpResponseStatus(Uri.create("http://localhost:9000/api/service"), 202, "status text", "json"))
  respBuilder.accumulate(new DefaultHttpHeaders().add("Content-Type", "application/json"))
  respBuilder.accumulate(new CacheableHttpResponseBodyPart("{\n\"id\":\"job-1\",\n\"lines\": [\n\"62812ce276aa9819a2e272f94124d5a1\",\n\"13ea8b769685089ba2bed4a665a61fde\"\n]\n}".getBytes(), true))
  val resp = new AhcWSResponse(respBuilder.build())

  val outputWriter = OutputWriter

  val expected = ("\"job-1\"", List("\"62812ce276aa9819a2e272f94124d5a1\"", "\"13ea8b769685089ba2bed4a665a61fde\""), "_SUCCESS")
  "Output Writer" should "handle response from api call" in {
    val actual = outputWriter.handleResponse(resp, "job-1")
    println("the actual : " + actual)
    actual shouldEqual(expected)

  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2015-09-08
    相关资源
    最近更新 更多