web-dev-qa-db-fra.com

POST demande échoue (test de repos assuré)

J'ai un problème avec la demande de POST avec l'assurance du repos.

Ce code fonctionne:

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

Mais j'essayais d'utiliser des méthodes param() ou parameter() comme celle-ci:

Celui-ci donne: 

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

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

Ce: 

    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>);

Et ça: 

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

Je suis à court d'idées ce qui ne va pas.

Ce que j'essaie de faire est d’éviter d’écrire des jsons complets pour tous les tests, ce sera plus rapide si je peux sauter tous les "" et {}. Est-ce que mon approche est correcte?

14
Purple

Regardons votre premier exemple:

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

Dans ce cas, vous insérez { "key" : "val" } (en tant que texte) dans le corps de la requête. Ce texte se trouve être JSON. Du point de vue de REST Assured, vous auriez aussi bien pu mettre { "key" : "val", qui n'est pas un code JSON valide. Votre serveur répond correctement car le serveur serveur requiert et comprend JSON. Il comprend que le corps doit être JSON puisque vous passez JSON en tant que type de contenu.

Alors regardons votre deuxième exemple:

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

Ici, votre service renvoie 415 car il vous manque le type de contenu JSON. Qu'est-ce qui se passe lorsque vous utilisez param ou parameter avec POST est que vous créez des paramètres de formulaire. Les paramètres de formulaire sont également envoyés dans le corps de la requête, mais les paramètres de formulaire ne sont pas JSON! Spécifier "key" et "val" comme paramètre de formulaire sera identique à celui-ci:

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

Donc, dans votre deuxième exemple, il y a en fait deux problèmes:

  1. Vous n'envoyez pas de JSON
  2. Vous avez le mauvais type de contenu

Et à cause de (2) vous obtenez 415 du serveur

Passons à votre troisième exemple:

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

Ce qui se passe (probablement) ici est que votre serveur ne contient pas de corps de réponse car il s'attend à ce que la requête inclue "application/json" en tant que type de contenu. Donc, il n'y a aucun corps à affirmer (la demande est fausse)! La réponse contient uniquement le statut 415 (ligne) en tant qu'en-tête.

Ce qui nous amène à votre dernier exemple: 

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

Vous indiquez ici REST. Assuré de traiter un type de contenu manquant comme étant JSON, mais le problème (encore une fois) est que votre serveur ne renvoie aucun corps de réponse, ce qui ne résoudra donc pas le problème. 

Solution:

Vous devez mettre un framework de mappage d'objets JSON pris en charge (Jackson, Faster Jackson, JSON simple ou Gson) dans votre chemin de classe (par exemple jackson-databind) et créer simplement une carte comme décrit dans la 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)); 

Depuis que la création de cartes en Java est assez prolixe, je fais habituellement quelque chose comme ceci si j'ai des cartes imbriquées:

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)); 

Ou vous créez une représentation DTO de vos données et passez simplement un objet à REST.

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

Vous pouvez en lire plus dans la documentation sur le mappage d'objet }.

13
Johan

Je cherchais une réponse et je l'ai compris aussi .. 

ajoutez un fichier à votre dossier src/test/resouces et ajoutez ce code à votre test. Devrait être tout bon 

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