7

我正在使用 Jersey 进行 REST API 实现。对于PATCH(部分更新),我已经实现了我自己的自定义实现,PATCH因为 Jersey 不支持它。

现在我试图弄清楚如何围绕该实现编写功能测试。我正在将球衣测试框架用于在该框架中具有该支持的其他方法(、、、、PUTPOSTGETDELETE

有没有办法可以扩展球衣测试框架实现来编写我的功能测试PATCH?如果没有,是否有任何其他可用的测试框架可用于测试我的 JerseyPATCH实现?

如果有人可以提供任何示例,那就太好了。

4

4 回答 4

6

假设您的实现包含这样的自定义注释

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

这不是ClientAPI 的直接问题,而是较低级别的 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);
    }
}
于 2015-04-08T01:39:00.873 回答
4

要在不进行任何额外配置的情况下发送HTTP PATCHvia :JAX RS Client API

 client.target("$baseUrl$restUsersUrl/$userId")
                .request("application/json")
                .build("PATCH", Entity.entity(json2Update, MediaType.APPLICATION_JSON))
                .invoke()
于 2016-03-29T16:20:30.077 回答
3

注释@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();

WhereSET_METHOD_WORKAROUND用于避免协议异常,如@peeskillet 所示:

java.net.ProtocolException: Invalid HTTP method: PATCH
于 2017-11-19T20:11:44.887 回答
-1

使用简单的字符串,这对我有用。但是当 Patch 方法不接受并返回一个简单的字符串时,有谁知道如何做到这一点?请参阅下面的示例。Response 中的返回类型与传递参数的类型不同。两者都不是简单的类型。我总是得到 400 和/或它无法构造 ObjectPatch 实例的消息,而不是 200。我明白这一点,因为它是一个只有应用方法的接口。但不知何故,它在运行时设法从中构造了一个 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();
    }
于 2020-06-03T13:38:30.843 回答