Java POST 请求失败(放心测试)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31992532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:53:13  来源:igfitidea点击:

POST request fails (rest-assured test)

javajsonhttp-postrest-assured

提问by Purple

I have problem with making POST request with rest-assured.

我在放心地发出 POST 请求时遇到问题。

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:

但我试图使用param()或这样的parameter()方法:

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>.

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

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

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?

我想要做的是避免为所有测试编写完整的 json,如果我可以跳过所有 "" 和 {},速度会更快。我的方法正确吗?

采纳答案by Johan

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));
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 serverrequires and understands JSON. It understands that the body should be JSON since you passing JSON as content-type.

这里发生的事情是您将{ "key" : "val" }(作为文本)放入请求正文中。此文本恰好是 JSON。从 REST Assured 的角度来看,您也可以放置{ "key" : "val"无效的 JSON。您的服务器正确响应,因为服务器需要并理解 JSON。它知道主体应该是 JSON,因为您将 JSON 作为内容类型传递。

So let's look at your second example:

所以让我们看看你的第二个例子:

given().parameter("key", "val").                                      
        when().post(url + resource).then().assertThat().statusCode(200);
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 paramor parameterwith POSTis 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:

此处您的服务返回 415,因为您缺少 JSON 内容类型。当您使用paramparameter使用时会发生什么POST是您创建表单参数。表单参数也在请求正文中发送,但表单参数不是 JSON!像您一样指定“key”和“val”作为表单参数将与此相同:

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:

所以在你的第二个例子中实际上有两个问题:

  1. You're not sending JSON
  2. You have the wrong content-type
  1. 您没有发送 JSON
  2. 你有错误的内容类型

And because of (2) you get 415 from the server

因为 (2) 你从服务器得到 415

Moving on to your third example:

继续你的第三个例子:

given().parameter("key", "val").                                                         
            when().post(url + resource).then().assertThat().body("otherVal", equalTo(otherVal));
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.

这里(可能)发生的是您的服务器不包含响应正文,因为它希望请求包含“application/json”作为内容类型。所以没有主体可以断言(请求错误)!响应仅包含 415 状态(行)作为标头。

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

在这里,您指示 REST Assured 将丢失的内容类型视为 JSON,但问题(再次)是您的服务器根本不返回任何响应正文,因此这无济于事。

Solution:

解决方案:

You should put a supported JSON object-mapping framework (Hymanson, Faster Hymanson, Simple JSON or Gson) in your classpath (for example Hymanson-databind) and just create a map as described in the documentation:

您应该在类路径(例如Hymanson-databind)中放置一个受支持的 JSON 对象映射框架(Hymanson、Faster Hymanson、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)); 

Since creating maps in Java is quite verbose I usually do something like this if I have nested maps:

由于在 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)); 

Or you create a DTO representation of your data and just pass an object to REST Assured:

或者您创建数据的 DTO 表示,然后将对象传递给 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.

您可以在对象映射文档 中阅读更多内容

回答by user6506244

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

将文件添加到您的 src/test/resouces 文件夹并将此代码添加到您的 test 。应该都很好

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