I have problem with making POST request with rest-assured.
This code works:
given().contentType(ContentType.JSON).body("{\"key\": \"val\"}").
when().post(url + resource).then().assertThat().statusCode(200).body("otherVal", equalTo(otherVal));
But I was trying to use param()
or parameter()
methods like that:
This one gives:
given().parameter("key", "val").
when().post(url + resource).then().assertThat().statusCode(200);
Expected status code <200> doesn't match actual status code <415>.
This:
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>);
And This:
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
I have run out of ideas whats wrong.
What I'm trying to do is to avoid writing full jsons for all test, it will be faster if I could skip all "" and {}. Is my approach correct?
We can use Assertion in response in Rest Assured. To obtain the Response we need to use the methods - Response. body or Response. getBody.
Hamcrest Matchers are optional, and are not strictly needed for REST Assured. They allow us to write more expressive unit tests. Gson is automatically used by REST Assured for JSON (de)serialization, as we will see in the examples. Rest Assured can also work with Jackson, if that is available in the classpath.
Let's look at your first example:
given().contentType(ContentType.JSON).body("{\"key\": \"val\"}"). when().post(url + resource).then().assertThat().statusCode(200).body("otherVal", equalTo(otherVal));
What happens here is that you put { "key" : "val" }
(as text) into the body of the request. This text happens to be JSON. From REST Assured's perspective you might as well could have put { "key" : "val"
which is not valid JSON. Your server responds correctly since the server requires and understands JSON. It understands that the body should be JSON since you passing JSON as content-type.
So let's look at your second example:
given().parameter("key", "val"). when().post(url + resource).then().assertThat().statusCode(200);
Here your service returns 415 because you're missing the JSON content-type. What happens when you use param
or parameter
with POST
is that you create form parameters. Form parameters are also sent in the request body BUT form parameters are not JSON! Specifying "key" and "val" as form parameter like you do will be the same as this:
given().contentType("x-www-form-urlencoded").body("key=val").when().url + resource).then().assertThat().statusCode(200);
So in your second example there's actually two problems:
And because of (2) you get 415 from the server
Moving on to your third example:
given().parameter("key", "val"). when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));
What (probably) happens here is that your server doesn't contain a response body because it expects the request to include "application/json" as content-type. So there is no body to assert (the request is wrong)! The response only contains the 415 status (line) as a header.
Which leads us to your last example:
RestAssured.defaultParser = Parser.JSON; given().parameter("key", "val"). when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));
Here you instruct REST Assured to treat a missing content-type as JSON but the problem (again) is that your server doesn't return any response body at all so this won't help.
Solution:
You should put a supported JSON object-mapping framework (Jackson, Faster Jackson, Simple JSON or Gson) in your classpath (for example jackson-databind
) and just create a map as described in the 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));
Since creating maps in Java is quite verbose I usually do something like this if I have nested maps:
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));
Or you create a DTO representation of your data and just pass an object to REST Assured:
MyDTO myDTO = new MyDTO(...);
given().
contentType(ContentType.JSON).
body(myDTO).
when().
post(url + resource).
then().
statusCode(200).
body("otherVal", equalTo(otherVal));
You can read more in the object-mapping documentation.
I was looking for answer and I figured it out too ..
add a file to your src/test/resouces folder and add this code to your test . Should be all good
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"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With