testing - Jersey 测试 - 带有 JSON 请求的 Http Delete 方法

标签 testing junit jersey http-delete jersey-test-framework

我正在使用 Jersey Test 来测试 Rest 服务 DELETE 方法:

@DELETE
@Path("/myPath")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public MyResponse myMethod(MyRequest myRequest) {

我尝试过下面的示例和其他方法:

Entity<MyRequest> requestEntity = Entity.entity(new MyRequest(arg1, arg2), MediaType.APPLICATION_JSON);

target(MY_URI).request(MediaType.APPLICATION_JSON).method("DELETE", requestEntity)

target(MY_URI).request(MediaType.APPLICATION_JSON).build("DELETE", requestEntity).invoke();

但是它不起作用。

如何在Jersey测试中进行Http删除?

最佳答案

根据HTTP规范

If a DELETE request includes an entity body, the body is ignored

虽然很多服务器仍然支持实体主体,但我想是因为这个 Jersey 认为主体违反了 HTTP 合规性。 Jersey 验证是否符合客户要求。要绕过此验证,您可以设置客户端属性

ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION

If true, the strict validation of HTTP specification compliance will be suppressed.

By default, Jersey client runtime performs certain HTTP compliance checks (such as which HTTP methods can facilitate non-empty request entities etc.) in order to fail fast with an exception when user tries to establish a communication non-compliant with HTTP specification. Users who need to override these compliance checks and avoid the exceptions being thrown by Jersey client runtime for some reason, can set this property to true. As a result, the compliance issues will be merely reported in a log and no exceptions will be thrown.

Note that the property suppresses the Jersey layer exceptions. Chances are that the non-compliant behavior will cause different set of exceptions being raised in the underlying I/O connector layer.

This property can be configured in a client runtime configuration or directly on an individual request. In case of conflict, request-specific property value takes precedence over value configured in the runtime configuration.

The default value is false.

JerseyTest 中配置它,你可以这样做

@Override
public void configureClient(ClientConfig config) {
   config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
}

假设您通过调用 target(..) 提出请求JerseyTest的方法,以上配置将适用于所有请求。如果您只想删除某些请求的验证,您还可以在 WebTarget 上设置该属性。并且不进行上述配置。

target(...).property(...).request()...

编辑

我可能提到的另一件事是 Grizzly 是不支持该实体的服务器之一, unless configured 。我不太确定如何在 JerseyTest 中配置它。因此,如果您使用 Grizzly 测试提供程序,它甚至可能无法在服务器端工作。

如果是这种情况,你尝试使用内存测试提供程序,或者使用jetty提供程序

编辑 Grizzly 配置

编辑由Emanuele Lombardi提供

您可以使用以下代码片段配置 Grizzly 测试提供程序:

@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
    return new TestContainerFactory() {

        private final GrizzlyTestContainerFactory grizzlyTestContainerFactory = new GrizzlyTestContainerFactory();

        @Override
        public TestContainer create(URI baseUri, DeploymentContext deploymentContext) {
            TestContainer testContainer = grizzlyTestContainerFactory.create(baseUri, deploymentContext);
            try {
                HttpServer server = (HttpServer) FieldUtils.readDeclaredField(testContainer, "server", true);
                server.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true);
            } catch (IllegalAccessException e) {
                fail(e.getMessage());
            }
            return testContainer;
        }
    };
}

应在 GrizzlyServer 启动之前调用以下方法。

server.getServerConfiguration().setAllowPayloadForUndefinedHttpMethods(true)‌​;

使用反射检索服务器实例(在此示例中通过 org.apache.commons.lang3.reflect.FieldUtils#readDeclaredField )。
此代码一直有效,直到 server字段名称未更改为 GrizzlyTestContainerFactory#GrizzlyTestContainer ,但对我来说似乎是一个合理的方法,至少在单元测试中是这样。

关于testing - Jersey 测试 - 带有 JSON 请求的 Http Delete 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36310863/

相关文章:

python - 在 Django 中运行 python manage.py test 时如何强制使用新数据库?

java - Mockito - 使用参数模拟方法

spring-boot - 如何在 spring-boot 应用程序中为 swagger-ui 指定我的 restful API

java - 部署使用 jersey api 创建的 war 文件

java - Jersey webservice 可扩展的下载文件和回复客户端的方法

testing - 在 Soap-UI 中使用 groovy 脚本检索项目的环境列表

javascript - 在 Meteor 中使用 Jasmine 测试异步函数

scala - 如何使用Play Framework读取测试代码中的资源?

junit - 如何让 JUnit 让我在一个测试用例中设置变量,并在其他测试用例中访问它们(如果它们位于同一类中)

java - 使用mockito调用Service类的嵌套方法时出现NullPointerException