当前位置: 首页 > 知识库问答 >
问题:

保证Rest-运行不同的API调用时不清除“多部分”参数

孙宏扬
2023-03-14

我有一个包含多个场景(获取、发布等)的功能文件。有一个特殊的顺序-

  1. 场景1-POST请求使用“多部分”数据运行

首先,在运行POST请求时,以下是请求信息-

Request method: POST
Request URI:    <<Request URL>>
Proxy:          <none>
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        X-AUTH-TOKEN= <<AuthToken>>
            Accept=*/*
            Content-Type=multipart/form-data; boundary="sVIVdkx_Idma6CgU58sVMDuGK4e34kqBOPeoObL"
Cookies:        <none>
Multiparts:     ------------
            Content-Disposition: form-data; boundary="sVIVdkx_Idma6CgU58sVMDuGK4e34kqBOPeoObL"; name = files; filename = debug.log
            Content-Type: application/octet-stream

            <<log file location>>
            ------------
            Content-Disposition: form-data; boundary="sVIVdkx_Idma6CgU58sVMDuGK4e34kqBOPeoObL"; name = body; filename = Test_new.json
            Content-Type: application/json

            <<Static JSON Payload location>>
Body:           <none>

如上所述,这是一个POST请求,其中“Content-Type”是“multipart/form-data”,“Multipart”参数包含静态JSON有效负载以及要上传的文件。这是通过以下代码完成的-

    RequestSpecification reqSpec_Int = getReqSpec.header("Content-Type", "multipart/form-data").
                            multiPart("files",uploadFiles).
                            multiPart("body", updateVinJsonFile, "application/json");

这工作正常。但是在这个POST调用之后,我需要运行GET调用(这是一个不同的场景),其中“Content-Type”是“Application/json”,“Multipart”参数中应该没有任何内容。但是当我运行这个GET API调用时,“Multipart”参数仍然显示之前POST调用的数据。请参阅下面-

Request method: GET
Request URI:    <<GET URL>>
Proxy:          <none>
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        X-AUTH-TOKEN= <<authToken>>
            Accept=*/*
            Content-Type=application/json
Cookies:        <none>
Multiparts:     ------------
            Content-Disposition: application/json; name = files; filename = debug.log
            Content-Type: application/octet-stream

            <<log file location>>
            ------------
            Content-Disposition: application/json; name = body; filename = Test_new.json
            Content-Type: application/json

            <<Static JSON Payload location>>
Body: <none>

由于这个原因,我得到了以下例外-

java.lang.IllegalArgumentException: Content-Type application/json is not valid when using multiparts, it must start with "multipart/" or contain "multipart+".

在POST调用完成后,有没有办法清除这个“Multiparts”参数?这样就不会收到电话了。

请注意——如上所述,此多部分设置是使用RequestSpecification完成的。对于每个场景,该引用在开始时都为空。

添加下面的代码-

下面是功能文件-

@EndToEndTest   
Scenario: Update API Call

Given "TEST" Authentication Token for "POST" "MULTIPART" Request
When User calls "<<UpdateAPICall>>" call with "POST" Http Request and Params
Then API call is successful

@EndToEndTest   
Scenario: Get API Call

Given "TEST" Authentication Token for "GET" "OCTET" Request
When User calls "<<GetAPICall>>" call with "GET" Http Request and Params
Then API call is successful

下面是步骤定义代码-

RequestSpecification reqSpec;
Response response;
static List<String> instructionFileList = new ArrayList<String>();
static String authToken;
static int jobId;
static int vinId;
boolean apiCallSuccess;

@Given("{string} Authentication Token for {string} {string} Request")
public void authentication_token_for_request(String environment, String method, String contentType) throws Exception {
    System.out.println("Authentication Token - "+authToken);
    RequestSpecification reqSpec_Int = null;
    
    File updateVinJsonFile = new File(getPropertyValue("updateJobVINJSON"));
    File uploadFiles = new File(getPropertyValue("fileUpload"));
    
    if(environment.equalsIgnoreCase("TEST")) {
        if(method.equalsIgnoreCase("GET")) {
            switch(contentType) {
                case "FORMURL":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "application/x-www-form-urlencoded");
                    break;
                case "OCTET":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "application/octet-stream");
                    break;
            }
        }
        else if (method.equalsIgnoreCase("POST")) {
            switch (contentType) {
                case "JSON":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "application/json");
                    break;
                case "MULTIPART":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "multipart/form-data").
                            multiPart("files",uploadFiles).
                            multiPart("body", updateVinJsonFile, "application/json");
                    break;
            }
        }           
    }
            
    reqSpec = given()
            .spec(reqSpec_Int).log().all()
            .header("X-AUTH-TOKEN",authToken);
}

@When("User calls {string} call with {string} Http Request and Params")
public void user_call_with_http_request_and_params(String resource, String method) {
    
    SoftAssert softAssert = new SoftAssert();       
    String finalResourceName = null;
    APIResources resourceAPI = APIResources.valueOf(resource);
    System.out.println("Resource Name - "+resourceAPI.getResource());
    
    try {
        if(resource.equalsIgnoreCase("<<UpdateAPI>>")) {
            for(int vinId:vinList) {
                finalResourceName = resourceAPI.getResource()+vinId;
                System.out.println("Final Resource Name - "+finalResourceName);
                response = reqSpec.when().post(finalResourceName);
                if(response.getStatusCode() == 200) {
                    System.out.println("API Call successful with Status Code - "+response.getStatusCode());
                    apiCallSuccess = true;
                }
                else {
                    System.out.println("API Call is not successful with Response - "+response.asString());
                    apiCallSuccess = false;
                }
            }
        }
        else if(resource.equalsIgnoreCase("<<GetAPI>>")) {
            for(String instruction:instructionFileList) {
                finalResourceName = resourceAPI.getResource()+jobId+"/instructionfile/"+instruction+".pdf";
                System.out.println("Final Resource Name - "+finalResourceName);
                Thread.sleep(4000);
                response = reqSpec.when().log().all().get(finalResourceName);
                if(response.getStatusCode() == 200) {
                    System.out.println("API Call successful with Status Code - "+response.getStatusCode());
                    apiCallSuccess = true;
                }
                else if(response.getStatusCode() == 500) {
                    JsonPath jj = CommonMethods.rawToJson(response.asString());
                    if(jj.get("error").toString().equalsIgnoreCase("Internal Server Error") && jj.get("exception").toString().equalsIgnoreCase("java.lang.NullPointerException")) {
                        System.out.println("API Call successful with Status Code - "+response.getStatusCode());
                        apiCallSuccess = true;
                    }
                    else {
                        System.out.println("API Call is not successful with Response - "+response.asString());
                        apiCallSuccess = false;
                    }
                }
            }
        }
   }

如前所述,在每个场景的开头,Request estSpeation引用'reqSpec'为空。当执行到达“GetAPICall”的下线时,我会得到提到的异常-

response = reqSpec.when().log().all().get(finalResourceName);

另请注意-如果我在POST Call之前运行GET调用,它运行正常。

共有1个答案

高奇
2023-03-14

据我所知,问题是RequestSpecification reqSpec,它仍然包含第一次运行的配置。我的建议是在调用api后将其设置为null

代码是:

@When("User calls {string} call with {string} Http Request and Params")
public void user_call_with_http_request_and_params(String resource, String method) {
    
    ...other code
    reqSpec = null; //At the end of method
}

@When("User calls {string} call with {string} Http Request and Params")
public void user_call_with_http_request_and_params(String resource, String method) {
    
    ...
    
    try {...}
    finally {
        reqSpec = null;
    }
}
 类似资料:
  • 如何使用ajax或XMLHttpRequest从javascript调用RESTAPI,以使用内容类型:multipart/form data上载文件。 文件内容是二进制格式的,但我调用的API具有以下请求格式:Authorization:Bearer 我使用以下代码段上传文件内容: 其中formData是二进制格式的文件内容。请建议这是正确的方法还是应该以不同的方式处理。我使用的文件类型是IFC

  • 我试图用Cucumber,用不同的参数并行运行多个testng套件。对于每个tesng套件,我试图传递不同的浏览器、testinfo等等。我想通过maven命令行选项来实现这一点。我关注了https://rationaleemotions.wordpress.com/2016/03/29/parallel-execution-of-multiple-testng-suites/#comment-1

  • 我有一个相当普遍或独特的要求。例如,我有以下列表:

  • 问题内容: 我想验证以下行为的方法如下。 在我的@Test类中,我希望做这样的事情来验证是否使用“ exception.message”和再次使用“ exception.detail”进行了调用 但是Mockito抱怨​​如下 我如何告诉Mockito检查两个值? 问题答案: 进一步的阅读使我尝试使用ArgumentCaptors和以下作品,尽管比我想要的更为冗长。

  • 我是API测试的新手。我正在使用Rest保证自动化RestAPI,并且在验证获取请求时遇到了困惑。 API根据从搜索UI接收的搜索参数返回一组结果。网址为

  • 当我多次调用同一个函数时,每次都传递了不同的参数,我会这样做: 有没有更方便的方法做到这一点呢?