我在创建用于单元测试的模拟响应对象时遇到了问题。我使用< code > org . glassfish . jersey . core . jersey-client 版本2.3.1来实现我的RESTful客户端,使用< code>mockito版本1.9.5来帮助我处理模拟对象。下面是我的测试代码:
@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();
时会出现此问题。下面是该方法的代码:
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()方法和手动创建的响应。当它到达<code>响应时。readEntity(resourceListType) 指令中,Jersey抛出以下异常:<code>java.lang.IllegalStateException-出站消息不支持此方法。。经过大量的研究和调试,由于某些原因,当我使用响应生成器(如<code>Response)创建响应时,结果证明了这一点。ok(expectedResource,MediaType.APPLICATION_JSON)。build()它将其创建为OutboundResponse,而不是InboundRespose。只有后者才允许使用<code>响应。readEntity()方法。如果是OutboundResponse,则抛出异常。
但是,我找不到任何方法将手动创建的响应转换为InboundResponse。所以我的测试注定要失败。你们知道我在这里能做什么吗?我不想用Mockito来嘲笑响应对象,因为我认为这可能是一种代码味道,因为它违反了Demeter法则。说真的,我已经没有主意了。像这样的事情应该简单明了。
我自己也遇到了这个问题,试图通过使用<code>Response.ok(实体)将客户端模拟为远程服务。build()然后允许我的客户机代码对来自伪造服务器的响应执行response.readEntity(…)
。
我在中讨论这个问题https://codingcraftsman.wordpress.com/2018/11/26/testing-and-mocking-jersey-responses/
问题是< code>Response.build()方法旨在生成出站响应,该响应在被真实客户端接收和反序列化之前应该被序列化。< code>readEntity方法应在反序列化时调用。
正如其他发帖人所观察到的那样,在出站响应
上阅读实体
将为您提供您放入的确切实体对象。您甚至可以将其投射到所需的任何类型。当然,这不适用于真正的入站响应,因为入站响应仅具有来自服务器的入站流的文本/二进制文件。
我编写了以下代码,以允许我使用 mockito 强制出站响应假装为入站响应
:
/**
* Turn a locally made {@link Response} into one which can be used as though inbound.
* This enables readEntity to be used on what should be an outbound response
* outbound responses don't support readEntity, but we can fudge it using
* mockito.
* @param asOutbound response built as though being sent to the received
* @return a spy on the response which adds reading as though inbound
*/
public static Response simulateInbound(Response asOutbound) {
Response toReturn = spy(asOutbound);
doAnswer(answer((Class<?> type) -> readEntity(toReturn, type)))
.when(toReturn)
.readEntity(ArgumentMatchers.<Class<?>>any());
return toReturn;
}
// use the getEntity from the real object as
// the readEntity of the mock
@SuppressWarnings("unchecked")
private static <T> T readEntity(Response realResponse, Class<T> t) {
return (T)realResponse.getEntity();
}
我有这个错误,因为当您使用响应生成器
时,它会返回一个无法使用readEntity()
处理的Out边界JaxrsACK
消息。
我注意到只有在直接调用Jax-RS组件时才出现这个错误。例如,如果我用@Path(“/default”)
注释了DefaultController
,并且如果我试图直接调用它的方法,我就不能使用readEntity()
,并且出现了与您相同的错误。
defaultController.get();
现在,当我使用 grizzly2 测试提供程序并使用客户端来定位 Rest Url(在前面的案例中,它是 /default
)时,我在响应中收到的消息是 ScopedJaxrsResponse。然后我可以使用readEntity()
方法。
target("/default").request.get();
在您的案例中,您嘲笑了simpleClient,以便使用使用响应生成器
构建的响应进行回复,该响应不是由jersey处理的。这与直接调用我的DefaultController
方法相当。
在不嘲笑readEntity()
方法的情况下,我建议您找到一种方法,让您的响应由泽西处理并变成ScopedJaxrsACK
。
希望有所帮助。
您还可以使用Mockito模拟响应:
final Response response = Mockito.mock(Response.class);
Mockito.when(response.getStatus()).thenReturn(responseStatus);
Mockito.when(response.readEntity(Mockito.any(Class.class))).thenReturn(responseEntity);
Mockito.when(response.readEntity(Mockito.any(GenericType.class))).thenReturn(responseEntity);
响应状态是与响应相关联的状态代码,响应Enitty当然是您要返回的实体。您可以使用该模拟作为Mockito中的返回状态(例如... then返回(响应))。
在我的项目中,我为不同类型的模拟(在这种情况下是响应)创建生成器,所以我可以很容易地按需构建所需的模拟,例如,状态代码为200的响应和一些附加的自定义实体。
我已经完成了在glassfish v4中添加SSL证书的步骤。我已经通过浏览器和java swing客户端验证了它的有效性(我在客户端使用apache的http客户端库) 什么不工作是管理控制台!由于成功导入SSL,我不能再连接到管理控制台,http://www.myhost.com:4848,我仍然得到登录屏幕,总是工作的管理员用户名/密码组合已停止工作。我也注意到当尝试部署一个网络应用程序从n
问题内容: 我正在尝试使用Jersey客户端模拟对我的Web服务的HTTP请求。我尝试实现文档中的简单示例。这是我的短代码: 我什至没有实现整个示例,因为当前我在最后一行收到一个异常: 我只将此依赖项添加到我的: 我试图用谷歌搜索问题,以及调试应用程序,但我真的看不出问题出在哪里。 编辑 所有Maven依赖项: 问题答案: 这看起来像与JAX-RS API版本(包含MultiValuedMap)有
我想返回一个临时重定向,使用AsyncACK。 下面的“工作”(因为没有错误),但似乎不是异步的(它一次处理一个请求)。 这应该工作吗?如果我明确需要像https://jersey.github.io/documentation/latest/async.html#d0e9895一样启动一个新线程,返回响应是什么样子的?
问题内容: 我正在下载Java EE,似乎有许多不同的下载选项。我不确定应该选择哪一个。Java EE似乎与GlassFish打包在一起。谁能告诉我这是什么,它对我有什么好处? 其次,如果我只是想玩转并了解Java EE,那么对我来说下载的是什么?列出选项的链接在下面… Java EE下载选项 问题答案: 首先,将近五年前它被称为Java EE。首字母缩略词J2EE仍指5.0之前的旧Java EE
我将mysql驱动程序放入glassfish/admin1/lib,我在尝试与GlassFish 3.1.2建立连接时收到此错误 为SimpleCRUD_ConnectionPool Ping连接池失败。类名错误或未为:com设置类路径。mysql。jdbc。jdbc2。可选择的MysqlDataSource请检查服务器。记录更多细节。 野兔配置: 池名称:SimpleCRUD_Connectio
不确定发生了什么,但我不知道我的反应在哪里被劫持了。