无法调用“io.restassured.specification.RequestSpecification.get(java.net.URI)

Cannot invoke "io.restassured.specification.RequestSpecification.get(java.net.URI)

在 Youtube 上 tutorial video 之后,我正在学习从头开始创建 REST Assured 和 Cucumber 框架。

以下是步骤定义及其在 RestAssuredExtension 中调用的方法 class。

@Given("^I perform GET operation for \"([^\"]*)\"$")
    public void i_Perform_GET_Operation_For(String url) throws Throwable {
        RestAssuredExtension.GetOps(url);
    }
package utilities;

import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.response.ResponseOptions;
import io.restassured.specification.RequestSpecification;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;


public class RestAssuredExtension {

public static RequestSpecification Request;

    public RestAssuredExtension() {
        //Arrange
        RequestSpecBuilder builder = new RequestSpecBuilder();
        builder.setBaseUri("http://localhost:3000/");
        builder.setContentType(ContentType.JSON);
        var requestSpec = builder.build();
        Request = RestAssured.given().spec(requestSpec);
    }

    public static ResponseOptions<Response> GetOps(String url)  {
        //Act
        try {
            return Request.get(new URI(url));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }
}

在视频教程中,测试成功。但是当我 运行 自己测试时,会导致以下错误:

步骤失败 java.lang.NullPointerException: 无法调用“io.restassured.specification.RequestSpecification.get(java.net.URI)”,因为“utilities.RestAssuredExtension.Request”为空 在 utilities.RestAssuredExtension.GetOps(RestAssuredExtension.java:42) 在 steps.GETPostSteps.i_Perform_GET_Operation_For(GETPostSteps.java:21)

请问有人要吗?

从你给出的例子来看,我认为你还没有初始化RestAssuredExtension.Request字段。

在视频中(我快速浏览了一下),他们提供了一个钩子来在执行任何测试之前创建 RestAssuredExtension 的新实例。这将确保 public static class 变量 Request 已被初始化为非空值。

我的建议,如果你想减少对测试框架的依赖并使用静态方法:

public final class RequestExtension {
    
    private static RequestSpecification request;

    // Ensure that no one is able to create an instance and thereby bypass proper initalization
    private RequestExtension() {

    }

    // Ensures the initialization responsibility is within the class itself and not a hidden dependency for other users.
    private static void getInstance() {
        if (request == null) {
            RequestSpecBuilder builder = new RequestSpecBuilder();
            builder.setBaseUri("http://localhost:3000/");
            builder.setContentType(ContentType.JSON);
            var requestSpec = builder.build();
            request = RestAssured.given().spec(requestSpec);
        }
        return request;
    }        

    public static ResponseOptions<Response> GetOps(String url)  {
        // Initialize
        getInstance();
        // Act
        try {
            return request.get(new URI(url));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }
}

否则,将静态方法与对实例的依赖性混合在一起会不断地绊倒人们。将采用上述方法或从 class 中完全删除 static

public class RequestExtension {

    private RequestSpecification request; 

    public RestAssuredExtension() {
        //Arrange
        RequestSpecBuilder builder = new RequestSpecBuilder();
        builder.setBaseUri("http://localhost:3000/");
        builder.setContentType(ContentType.JSON);
        var requestSpec = builder.build();
        request = RestAssured.given().spec(requestSpec);
    }

    public ResponseOptions<Response> GetOps(String url)  {
        //Act
        try {
            return request.get(new URI(url));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }
}

有助于调试的一件事是遵循 Java 命名约定。 class 字段 RequestSpecification 的大写使其读作 class 而不是字段名称。 (Request vs request)视频中的情况相同,因此这是一个来源问题。 :)