搭建REST Assured+Cucumber框架调用GET接口时报Request空指针异常
报错根本原因
- 最直接的触发原因:定义的静态字段
Request从未被赋值。给Request初始化的代码全部写在RestAssuredExtension的公开构造方法里,但Cucumber执行测试步骤的全流程中,从来没有手动new过RestAssuredExtension的实例,构造方法根本不会被触发,Request保持Java引用类型默认的null值,最终调用Request.get()方法时直接抛出空指针。 - 附带的逻辑缺陷:即使构造方法被触发,现有URL处理逻辑也存在bug:你在请求规范里设置了baseUri为
http://localhost:3000/,但GetOps方法里却把传入的字符串直接封装成完整URI传入请求方法,这种写法会完全跳过baseUri的拼接逻辑——比如传/users这样的相对路径时,会直接触发URISyntaxException,因为URI构造器要求传入带协议头的完整地址。 - 代码设计缺陷:用构造方法给静态字段赋值属于典型反模式,多线程并行跑测试时会出现静态字段被覆盖的线程安全问题,且工具类的所有方法都是静态的,完全不需要对外暴露实例构造入口。
修复方案
按照下面的调整点逐点修改即可彻底解决问题:
- 把
Request的初始化逻辑从构造方法迁移到静态代码块,类加载时自动完成初始化,彻底消除空指针风险。 - 调整URL处理逻辑:不再手动将传入参数封装为
URI对象,直接传入接口相对路径,由RestAssured基于预设的baseUri自动拼接完整请求地址。 - 调整工具类封装:将无意义的公开构造方法改为私有,禁止外部误创建工具类实例;按照Java常量命名规范重写静态请求字段名,降低后续维护成本。
- 适配Cucumber特征文件的传参逻辑:步骤中传入的接口地址统一写为相对路径(如
/posts),不要传带协议头的完整URL,避免覆盖预设的baseUri配置。
修复后的完整工具类代码:
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; public class RestAssuredExtension { // 类加载时初始化的常量级请求规范,保证不会为null private static final RequestSpecification REQUEST_SPEC; // 静态代码块:类加载阶段执行初始化,不依赖实例构造 static { RequestSpecBuilder builder = new RequestSpecBuilder(); builder.setBaseUri("http://localhost:3000"); builder.setContentType(ContentType.JSON); REQUEST_SPEC = RestAssured.given().spec(builder.build()); } // 私有构造:禁止外部创建工具类实例 private RestAssuredExtension() {} public static ResponseOptions<Response> GetOps(String relativeApiPath) { // 直接传入相对路径,由RestAssured自动拼接baseUri return REQUEST_SPEC.get(relativeApiPath); } }
内容的提问来源于stack exchange,提问作者OB1 aka Kemosabi
相关产品推荐
相关产品推荐

