无法模拟Glassfish Jersey客户端响应对象 [英] Unable to Mock Glassfish Jersey Client response object

查看:247
本文介绍了无法模拟Glassfish Jersey客户端响应对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在创建一个模拟Response对象以用于我的单元测试时遇到了问题。我使用 org.glassfish.jersey.core.jersey-client 版本2.3.1来实现我的RESTful客户端和 mockito 版本1.9.5来帮助我模拟对象。这是我测试的代码:

I am having problems with creating a mock Response object to use with my unit tests. I am using org.glassfish.jersey.core.jersey-client version 2.3.1 to implement my RESTful client and mockito version 1.9.5 to help me with mock objects. Here is my test's code:

@Test
public void testGetAll() throws IOException {
    // Given
    String expectedResource = "expectedResource"

    final Response expectedRes =  Response.ok(expectedResource, MediaType.APPLICATION_JSON).build();
    String receivedResource;

    BDDMockito.given(this.client.getSimpleClient().getAllWithResponse()).willReturn(expectedRes);

    // When
    receivedResource = this.client.getAll();

    // Then
    Assert.assertNotNull("Request constructed correctly and response received.", receivedResource);
    Assert.assertEquals("Resource is equal to expected.", expectedResource, receivedResource);
}

this.client.getAll( );执行。这是该方法的代码:

The problem occurs when this.client.getAll(); is executed. Here is that method's code:

public String getAll() throws GenericAragornException, ProcessingException{
    Response response = this.simpleClient.getAllWithResponse();

    if (response.getStatus() != 200) {
        processErrorResponse(response);
    }

    String entity = response.readEntity(String.class);

    // No errors so return entity converted to resourceType.
    return entity;
}

请注意,我嘲笑this.simpleClient.getAllWithResponse()手动创建Response。当它到达 response.readEntity(resourceListType); 指令时,Jersey会抛出以下异常: java.lang.IllegalStateException - 出站方法不支持消息。。经过大量研究和调试后,出于某种原因,当我使用响应构建器(如 Response.ok(expectedResource,MediaType.APPLICATION_JSON).build(); 它会将其创建为OutboundResponse而不是 InboundResponse 。后者是唯一允许使用 Response.readEntity()方法的方法。如果它是 OutboundResponse ,则引发异常。

Note that I am mocking the this.simpleClient.getAllWithResponse() method with the manually created Response. When it reaches the response.readEntity(resourceListType); instruction, Jersey throws the following exception: java.lang.IllegalStateException - Method not supported on an outbound message.. After lots of research and debugging, it turns that, for some reason, when I create a Response using the response builder such as Response.ok(expectedResource, MediaType.APPLICATION_JSON).build(); it creates it as an OutboundResponse instead of as an InboundResponse. The latter are the only ones permitted to use the Response.readEntity() method. If it is an OutboundResponse, the exception is thrown.

但是,我找不到任何方法将手动创建的响应转换为InboundResponse 。所以我的测试是注定的:(你们/ gals对我在这里能做什么有所了解吗?我不想用Mockito模拟Response对象,因为我认为它可能是代码异味,因为它违反了定律Demeter。真诚的我在这里没有想法,像这样的事情应该简单明了。

However, I could not find any way of converting the manually created response to an InboundResponse. So my tests are doomed :(. Do you guys/gals have any idea of what I can do here? I don't want to mock the Response object with Mockito because I think it could be a code smell since it violates the Law of Demeter. Sincerely I am out of ideas here. Things like this should be simple and straightforward.

你使用 ResponseBuilder ,它会返回一个 OutboundJaxrsResponse 消息,这个消息不能用 readEntity )

I had this error because when you use the ResponseBuilder, it returns an OutboundJaxrsResponse message that can not be processed with readEntity().

我注意到,只有当我直接调用Jax-RS组件时才出现这个错误,例如,如果我有 DefaultController @Path(/ default)注释,如果我试图直接调用它的方法,我无法使用 readEntity()并且与您有相同的错误。

I noticed that I had this error only when I was calling the Jax-RS component directly. For exemple, if I have DefaultController annotated with @Path("/default") and if I tried to directly call its method, I could not use readEntity() and had the same error as you.

defaultController.get();

现在,当我使用grizzly2测试提供程序并使用客户端来定位Rest Url(在前面的例子中,它是 / default ),我收到的消息是ScopedJaxrsResponse。然后我可以使用 readEntity()方法。

Now, when I was using the grizzly2 test provider and using a client to target the Rest Url (in the previous case, it is /default), the message I received in response was a ScopedJaxrsResponse. And then I could use the readEntity() method.

target("/default").request.get();

在你的情况中,你嘲笑simpleClient以回应用<$ c $构建的响应c> ResponseBuilder 不是由球衣处理。它可以直接调用我的 DefaultController 方法。

In your case, you mocked the simpleClient in order to reply with a response built with ResponseBuilder that is not processed by jersey. It's comparable to calling directly my DefaultController method.

不嘲笑 readEntity()方法,我建议你找到一种方法让Jersey处理你的响应,并转换成 ScopedJaxrsResponse

Without mocking the readEntity() method, I suggest you to find a way to get your response processed by Jersey and turned into a ScopedJaxrsResponse.

希望有所帮助。

这篇关于无法模拟Glassfish Jersey客户端响应对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆