Ответ 1
Посмотрите на свой первый пример:
given().contentType(ContentType.JSON).body("{\"key\": \"val\"}"). when().post(url + resource).then().assertThat().statusCode(200).body("otherVal", equalTo(otherVal));
Что происходит, так это то, что вы помещаете { "key" : "val" }
(как текст) в тело запроса. Этот текст - это JSON. В REST Assured view вы также могли бы поставить { "key" : "val"
, который недействителен JSON. Ваш сервер отвечает правильно, так как сервер требует и понимает JSON. Он понимает, что тело должно быть JSON, поскольку вы передаете JSON как контент-тип.
Итак, давайте посмотрим на ваш второй пример:
given().parameter("key", "val"). when().post(url + resource).then().assertThat().statusCode(200);
Здесь ваш сервис возвращает 415, потому что вам не хватает содержимого контента JSON. Что происходит, когда вы используете param
или parameter
с POST
, это то, что вы создаете параметры формы. Параметры формы также отправляются в тело запроса, но параметры формы не являются JSON! Указание "ключ" и "val" в качестве параметра формы, как вы, будет таким же:
given().contentType("x-www-form-urlencoded").body("key=val").when().url + resource).then().assertThat().statusCode(200);
Итак, в вашем втором примере есть две проблемы:
- Вы не отправляете JSON
- У вас неправильный тип содержимого
И из-за (2) вы получаете 415 с сервера
Перейдем к вашему третьему примеру:
given().parameter("key", "val"). when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));
Что (возможно) происходит здесь, так это то, что ваш сервер не содержит тело ответа, потому что он ожидает, что запрос будет включать "application/json" в качестве типа контента. Так что нет тела для утверждения (просьба неверна)! Ответ содержит только статус 415 (строка) в качестве заголовка.
Что приводит нас к вашему последнему примеру:
RestAssured.defaultParser = Parser.JSON; given().parameter("key", "val"). when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));
Здесь вы инструктируете REST Assured обрабатывать отсутствующий тип содержимого как JSON, но проблема (опять же) заключается в том, что ваш сервер вообще не возвращает тело ответа, так что это не поможет.
Решение:
В свой путь к классам (например, jackson-databind
) вы должны поместить поддерживаемую инфраструктуру объектно-ориентированного JSON (Jackson, Faster Jackson, Simple JSON или Gson) и просто создать карту, как описано в документация:
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));
Вы можете прочитать больше в документации по сопоставлению объектов.