如何通过TestRunner与Cucumber注入Citrus的TestContext?
解决Citrus Java DSL中TestContext提取变量的问题
看起来你在尝试用Citrus提取REST响应中的数据到TestContext时踩了两个常见的坑,我来帮你梳理下问题和解决方案:
问题根源分析
- 空指针异常的原因:你单独用
@CitrusResource注入TestContext时,这个实例可能没有被Citrus正确初始化——因为Citrus的TestContext是和当前测试场景绑定的,通常是通过TestRunner来持有和管理的,单独注入容易出现初始化时机不对的问题。 - 变量找不到的原因:你手动
new TestContext()创建的是一个全新的上下文对象,和runner在测试中使用的上下文完全无关,所以你通过runner提取的ids变量根本不会存在于这个新上下文里。
正确的解决方案
核心思路是:通过TestRunner获取当前绑定的TestContext,不要单独注入或手动创建。
修正后的代码如下:
@CitrusResource private TestRunner runner; @When("^service sends request to get all orders$") public void get_Orders() { runner.http(action -> action.client(httpClientName) .send() .get(basePath)); } @Then("^Service gets response with preflight id: \"([^\"]*)\"$") public void verify_Orders(String preflightId) { runner.http(action -> action.client(httpClientName) .receive() .response(HttpStatus.OK) .contentType("application/json;charset=UTF-8") .extractFromPayload("$[*].styleId", "ids") // 提取变量到runner的上下文 .validate("$[*].styleId", everyItem(not(isEmptyOrNullString()))) .validate("$[*].styleId", hasItem(preflightId))); // 从runner持有的TestContext中获取变量,注意不要加${} List<String> ids = runner.getTestContext().getVariable("ids", List.class); // 这里就可以用ids做后续操作了 }
关键注意点
- 移除单独的
@CitrusResource TestContext注入,只保留TestRunner。 - 获取变量时,直接使用变量名
"ids",不要加${}——${}是Citrus在表达式中引用变量的语法,而getVariable()方法只需要传入变量名本身。 - 因为你提取的是
$[*].styleId(一个数组),所以最好用List.class来接收,而不是String.class,这样更符合数据结构。
这样修改后,你就能正确获取到从响应中提取的变量,用于后续测试步骤了。
内容的提问来源于stack exchange,提问作者Kirill Karpov
相关产品推荐
相关产品推荐

