web-dev-qa-db-ja.com

POSTリクエストが失敗する(安心テスト)

POSTリクエストを安心してリクエストできません。

このコードは機能します:

_given().contentType(ContentType.JSON).body("{\"key\": \"val\"}").    
        when().post(url + resource).then().assertThat().statusCode(200).body("otherVal", equalTo(otherVal)); 
_

しかし、私はそのようなparam()またはparameter()メソッドを使用しようとしていました:

これは与える:

_given().parameter("key", "val").                                      
        when().post(url + resource).then().assertThat().statusCode(200);  
_

_Expected status code <200> doesn't match actual status code <415>._

この:

_    given().parameter("key", "val").                                                         
            when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));  
_

Java.lang.IllegalStateException: Expected response body to be verified as JSON, HTML or XML but no content-type was defined in the response. Try registering a default parser using: RestAssured.defaultParser(<parser type>);

この:

_RestAssured.defaultParser = Parser.JSON;                                                   
given().parameter("key", "val").                                                       
        when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));
_

_Java.lang.IllegalArgumentException: The JSON input text should neither be null nor empty_

何が悪いのかアイデアが足りなくなった。

私がやろうとしていることは、すべてのテストに対して完全なjsonを書くことを避けることです。すべての ""と{}をスキップできれば、より速くなります。私のアプローチは正しいですか?

14
Purple

最初の例を見てみましょう:

given().contentType(ContentType.JSON).body("{\"key\": \"val\"}").    
        when().post(url + resource).then().assertThat().statusCode(200).body("otherVal", equalTo(otherVal));

ここで発生するのは、{ "key" : "val" }(テキスト)をリクエストの本文に挿入することです。このテキストはたまたまJSONです。 REST Assuredの観点からすると、有効なJSONではない{ "key" : "val"を置くこともできます。サーバーはserverなので正しく応答しますJSONを必要とし、理解します。JSONをcontent-typeとして渡すため、本文はJSONである必要があります。

それでは、2番目の例を見てみましょう。

given().parameter("key", "val").                                      
        when().post(url + resource).then().assertThat().statusCode(200);

ここでは、JSON content-typeがないため、サービスは415を返します。 paramまたはparameterPOSTとともに使用すると、フォームパラメータを作成することになります。フォームパラメータもリクエストの本文で送信されますが、フォームパラメータはJSONではありません。 「key」と「val」をフォームパラメータとして指定することは、次のようになります。

given().contentType("x-www-form-urlencoded").body("key=val").when().url + resource).then().assertThat().statusCode(200);

したがって、2番目の例では、実際には2つの問題があります。

  1. JSONを送信していません
  2. あなたは間違ったコンテンツタイプを持っています

(2)のため、サーバーから415を取得します

3番目の例に移ります。

given().parameter("key", "val").                                                         
            when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));

ここで(おそらく)発生するのは、リクエストにcontent-typeとして「application/json」が含まれることを想定しているため、サーバーに応答本文が含まれていないことです。したがって、アサートするボディはありません(リクエストは間違っています)。応答には、ヘッダーとして415ステータス(行)のみが含まれます。

これが最後の例です。

RestAssured.defaultParser = Parser.JSON;                                                   
given().parameter("key", "val").                                                       
        when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));

ここでは、REST欠落しているコンテンツタイプをJSONとして扱うことを保証しますが、サーバーが応答本文をまったく返さないため、これは役に立ちません。

ソリューション:

サポートされているJSONオブジェクトマッピングフレームワーク(Jackson、Faster Jackson、Simple JSONまたはGson)をクラスパス(たとえば、jackson-databind)に入れ、 documentation の説明に従ってマップを作成するだけです。 :

Map<String, Object>  jsonAsMap = new HashMap<>();
map.put("key", "val");

given().
        contentType(ContentType.JSON).
        body(jsonAsMap).
when().
        post(url + resource).
then().
        statusCode(200).
        body("otherVal", equalTo(otherVal)); 

Javaでマップを作成するのは非常に冗長であるため、ネストされたマップがある場合、通常は次のようにします。

given().
        contentType(ContentType.JSON).
        body(new HashMap<String,Object>() {{
             put("key1, "val1");
             put("key2, "val2");
             put("key3", asList("val3", "val4"));
             put("nested", new HashMap<String,String>() {{
                 put("key4", "val4");
                 put("key5", "val5");
             }});
        }}).
when().
        post(url + resource).
then().
        statusCode(200).
        body("otherVal", equalTo(otherVal)); 

または、データのDTO表現を作成し、オブジェクトをREST Assuredに渡すだけです。

MyDTO myDTO = new MyDTO(...);
given().
        contentType(ContentType.JSON).
        body(myDTO).
when().
        post(url + resource).
then().
        statusCode(200).
        body("otherVal", equalTo(otherVal)); 

詳細は object-mappingのドキュメント を参照してください。

13
Johan

私は答えを探していましたが、それもわかりました。

ファイルをsrc/test/resoucesフォルダーに追加し、このコードをテストに追加します。すべて良いはず

URL file = Resources.getResource("ModyNewFieldsReq.json");
String myRequest = Resources.toString(file,Charsets.UTF_8);

Response fieldResponse =  given ()
       .header("Authorization", AuthrztionValue)
       .header("X-App-Client-Id", XappClintIDvalue)
       .contentType("application/vnd.api+json")
       .body(myRequest).with()

     .when()
       .post(dataPostUrl)    

    .then()
       .assertThat()
       .log().ifError()
       .statusCode(200)
       .extract().response();

Assert.assertFalse(fieldResponse.asString().contains("isError"));
1
user6506244