2

私は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 Delete を作成するには?

4

1 に答える 1

3

HTTP仕様によると

DELETE リクエストにエンティティ本体が含まれている場合、本体は無視されます

多くのサーバーはまだエンティティ本体をサポートしていますが、このため、Jersey は本体を HTTP コンプライアンスに違反していると見なしていると思います。Jersey は、クライアントの要求への準拠を検証します。この検証を回避するには、クライアント プロパティを設定します。

ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION

true の場合、HTTP 仕様への準拠の厳密な検証が抑制されます。

デフォルトでは、Jersey クライアント ランタイムは特定の HTTP コンプライアンス チェック (どの HTTP メソッドが空でないリクエスト エンティティを容易にするかなど) を実行し、ユーザーが HTTP 仕様に準拠していない通信を確立しようとしたときに例外で失敗するようにします。これらのコンプライアンス チェックをオーバーライドし、何らかの理由で Jersey クライアント ランタイムによってスローされる例外を回避する必要があるユーザーは、このプロパティを true に設定できます。その結果、コンプライアンスの問題はログに報告されるだけで、例外はスローされません。

プロパティがジャージー レイヤーの例外を抑制することに注意してください。非準拠の動作により、基盤となる I/O コネクタ レイヤーでさまざまな例外セットが発生する可能性があります。

このプロパティは、クライアントのランタイム構成で、または個々の要求で直接構成できます。競合が発生した場合、リクエスト固有のプロパティ値がランタイム構成で構成された値よりも優先されます。

デフォルト値は false です。

で設定するにはJerseyTest、次のことができます

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

target(..)のメソッドを呼び出してリクエストを行っていると仮定するとJerseyTest、上記の構成はすべてのリクエストに適用されます。特定のリクエストの検証を削除するだけの場合WebTargetは、上記の構成を行わずにプロパティを設定することもできます。

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

編集

私が言及するかもしれないもう1つのことは、構成されていない限り、Grizzlyはエンティティをサポートしないサーバーの1つであるということです. JerseyTestでそれを構成する方法はよくわかりません。そのため、Grizzly テスト プロバイダーを使用している場合、サーバー サイドでも機能しない可能性があります。

この場合は、インメモリ テスト プロバイダーを使用するか、jetty プロバイダーを使用してみてください。

グリズリー構成の編集

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しますが、少なくとも単体テストでは妥当なアプローチのようです。

于 2016-03-30T14:05:02.730 に答える