Mock or build a Jersey InboundJaxrsResponse

2019-02-21 16:55发布

问题:

I'm fairly new developing jersey client, and has run into some problems with some testing. First off all I maybe should mention that my application is all client side, no server side stuff at all.

My problem is that I would like to create a Response object of instance InboundJaxrsResponse, so far I've tried to achieve this by mocking a Response using Mockito and ResponseBuilder.build()

Using Mockito:

Response response = mock(Response.class);
when(response.readEntity(InputStream.class))
    .thenReturn(ClassLoader.getSystemResourceAsStream("example_response.xml");

this works fine, when I read out the entity of the response with response.readEntity(InputStream.class) I get the entity as expected. However I need to read the entity from the response several times. in order to achieve this I use response.bufferEntity() before I read out the entity. The first time I read the entity all works fine, but the second time I get an exception I/O stream closed... Well I figured out mocking the method bufferEntity as well like following:

Response response = mock(Response.class);
when(response.bufferEntity()).thenCallRealMethod();
when(response.readEntity(InputStream.class))
    .thenReturn(ClassLoader.getSystemResourceAsStream("example_response.xml");

But this only results in a Error being thrown upon calling bufferEntity(), this is because bufferEntity() of Response is abstract.

My other attempt is by using ResponseBuilder.build() like following:

ResponseBuilder responseBuilder = Response.accepted(ClassLoader.getSystemResourceAsStream("example_response.xml"));
Response response = responseBuilder.build();

This declaration is fine and by debugging my response I can see that it got correct entity and so on. But this time when I call response.bufferEntity() I get an exception thrown saying that the operation is illegal for an OutboundJaxrsResponse so by building a response in this way resulting in wrong instance of Response.class:

So this ends up in three questions.

  1. Is this the way at all to mock/build objects of this types for testing?
  2. Is there a way to mock a inbound response?
  3. Is there a way to instead of creating a instance of OutboundJaxrsResponse with ResponseBuilder.build() creating a instance of InboundJaxrsResponse, or at least casting/converting an instance of OutboundJaxrsResponse to an instance of OutboundJaxrsResponse?

回答1:

I solved in this way:

@Spy Response response;

...

// for assignments in code under testing:
doReturn( response ).when( dwConnector ).getResource( anyString() );

// for entity and response status reading:
doReturn( "{a:1}".getBytes() ).when( response ).readEntity( byte[].class );
doReturn( 200 ).when( response ).getStatus();