1

在 Youtube 上的教程视频之后,我正在学习从头开始创建 REST Assured 和 Cucumber 框架。

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

@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”在实用程序中为空。RestAssuredExtension.GetOps(RestAssuredExtension.java:42 ) 在 steps.GETPostSteps.i_Perform_GET_Operation_For(GETPostSteps.java:21)

请问有接盘的吗?

4

1 回答 1

1

从您给出的示例中,我认为您尚未初始化该RestAssuredExtension.Request字段。

在视频中(我快速浏览了一下),它们提供了一个钩子来RestAssuredExtension在执行任何测试之前创建一个新的实例。这将确保公共静态类变量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;
    }
}

否则,将静态方法与对实例的依赖项混合在一起会不断绊倒人们。将与上述一起使用或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 命名约定。类字段的大写RequestSpecification使其读作类而不是字段名。( Requestvs request) 在视频中是一样的,所以它是一个源问题。:)

于 2021-02-04T20:47:05.263 回答