How to create a WSResponse object from string for Play WSClient

谁都会走 提交于 2020-07-20 10:53:09

问题


Documentation suggests testing API client based on WSClient using a mock web service, that is, create a play.server.Server which will respond to real HTTP requests.

I would prefer to create WSResponse objects directly from files, complete with status line, header lines and body, without real TCP connections. That would require less dependencies and run faster. Also there may be other cases when this is useful.

But I can't find a simple way to do it. It seems all implementations wrapped by WSResponse are tied to reading from network.

Should I just create my own subclass of WSResponse for this, or maybe I'm wrong and it already exists?


回答1:


The API for Play seems intentionally obtuse. You have to use their "Cacheable" classes, which are the only ones that seem directly instantiable from objects you'd have lying around.

This should get you started:

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

The mystery boolean values aren't documented. My guess is the boolean for BodyPart is whether that is the last part of the body. My guess for Headers is whether the headers are in the trailer of a message.




回答2:


I used another way, mocking WSResponse with Mockito:

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



回答3:


If you are using play-framework 2.8.x and scala, the below code can help us generate a dummy 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)

  }
}


来源:https://stackoverflow.com/questions/34753534/how-to-create-a-wsresponse-object-from-string-for-play-wsclient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!