[英]Using PATCH with Jersey Client API for unit testing
我正在使用 Jersey 进行 REST API 实现。 对于PATCH
(部分更新),我已经实现了我自己的PATCH
自定义实现,因为 Jersey 不支持它。
现在我想弄清楚如何围绕该实现编写功能测试。 我正在将 jersey 测试框架用于其他方法( PUT
、 POST
、 GET
、 DELETE
),这些方法在该框架中具有可用的支持。
有没有一种方法可以扩展 jersey 测试框架实现来编写我的PATCH
功能测试? 如果没有,是否还有其他测试框架可用于测试我的 Jersey PATCH
实现?
如果有人可以提供任何示例,那就太好了。
假设您的实现包含这样的自定义注释
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.HttpMethod;
@HttpMethod("PATCH")
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PATCH {}
试图与Client
做这样的事情
String response = target.request().method("PATCH", Entity.text("Hello"), String.class);
默认情况下不支持,并且会出现类似的异常
java.net.ProtocolException: Invalid HTTP method: PATCH
这不是直接使用Client
API 的问题,而是使用较低级别的 Java API 的问题。 似乎是一些安全限制。
使用客户端 API,我们可以通过设置属性来覆盖它
在JerseyTest
,配置Client
一种方法是覆盖configureClient
,并使用ClientConfig
设置属性。 您可以轻松地在Client
本身上设置属性,但要保持JerseyTest
框架的精神(我们不需要显式访问Client
,下面的示例将只是覆盖该方法
public class PatchTest extends JerseyTest {
@Path("patch")
public static class PatchResource {
@PATCH
@Produces(MediaType.TEXT_PLAIN)
public String getPatch(String request) {
return "Patched " + request;
}
}
@Override
protected void configureClient(final ClientConfig config) {
config.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true);
}
@Override
public Application configure() {
return new ResourceConfig(PatchResource.class);
}
@Test
public void doPatchTest() {
WebTarget target = target("patch");
String response = target.request().method("PATCH", Entity.text("Hello"), String.class);
Assert.assertEquals("Patched Hello", response);
System.out.println(response);
}
}
要通过JAX RS Client API
发送HTTP PATCH
而无需任何额外配置:
client.target("$baseUrl$restUsersUrl/$userId")
.request("application/json")
.build("PATCH", Entity.entity(json2Update, MediaType.APPLICATION_JSON))
.invoke()
注释@PATCH
现在在 JAX-RS 2.1 中可用。 您可以在服务器端实现此 HTTP 方法,例如:
@PATCH
public Response updateResource() { ... }
至于客户端,您可以执行以下操作:
Response r = ClientBuilder.newClient()
.target("http://localhost:8080/patch")
.request()
.build("PATCH", Entity.text("patch"))
.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true)
.invoke();
其中SET_METHOD_WORKAROUND
用于避免协议异常,如@peeskillet 所示:
java.net.ProtocolException: Invalid HTTP method: PATCH
使用简单的字符串,这对我有用。 但是当 Patch 方法不接受并返回一个简单的 String 时,有人知道如何做到这一点吗? 请参阅下面的示例。 Response 中的返回类型与传递的参数类型不同。 两者都不是简单的类型。 我总是得到 400 和/或无法构造 ObjectPatch 实例的消息,而不是 200。 我明白这一点,因为它是一个只有一个 apply 方法的接口。 但不知何故在运行时它设法从它构造一个 AttentionPatchResource 对象无论如何。 不幸的是,在使用 JerseyTest 框架时不是。
@PATCH
@Path("/something")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({ PatchMediaTypes.APPLICATION_MERGE_PATCH_JSON, PatchMediaTypes.APPLICATION_JSON_PATCH })
public Response updateAttention( //
@Parameter(schema = @Schema(implementation = AttentionPatchResource.class)) ObjectPatch patch) {
Attention attention = attentionService.find();
AttentionPatchResource patchResource = attentionAdapter.toPatchResource(attention);
AttentionPatchResource patchedResource = patch.apply(patchResource);
Attention patchedAttention = attentionAdapter.fromPatchResource(attention, patchedResource);
AttentionResource resource = attentionAdapter.toResource(patchedAttention);
return Response.status(Status.OK).entity(resource).build();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.