Citrus 框架:如何使 soap 响应/citrus 变量/citrus 函数 return 结果可用于 java

Citrus framework: How to make a soap response / citrus variable / citrus function return result available to java

我正在使用 Citrus 2.7.8 和 Cucumber 2.4.0。我正在进行 soap 调用并希望获得响应并对它进行一些高级解析以验证 graphql 响应是否具有匹配值。 (我知道当它只有一个元素时如何进行验证,但是当可能返回一个或多个元素(例如,1 辆车或 4 辆车)时,我需要能够处理的东西)。为了使我的验证非常动态并能够处理许多不同的 'quotes',我想存储对 Citrus 变量的响应,然后使其可供 java 读取文件并进行高级解析和验证。

TestContext 注入目前似乎不适用于 Cucumber(参见 https://github.com/citrusframework/citrus/issues/657),所以我在这里使用解决方法: 手动创建上下文。如果没有这个,我会在任何具有上下文的内容上得到一个 nullpointerexception。

我能够使用 Citrus 的消息功能来获取非常棒的肥皂响应。我在控制台中的 echo 语句显示它成功地将正确的值放入 citrus 变量中。但是我在将它提供给 java 时遇到了问题,这样我就可以打开它并对其进行解析。

我已将我的步骤定义文件缩减为仅包含相关代码。下面列出了我的几次尝试以及我在结果中遇到的问题。

是否有人对我如何成功解决上下文问题并将我的回复提供给 java 有任何想法?

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;

import com.consol.citrus.Citrus;
import com.consol.citrus.annotations.CitrusFramework;
import com.consol.citrus.annotations.CitrusResource;
import com.consol.citrus.config.CitrusSpringConfig;
import com.consol.citrus.context.TestContext;

import com.consol.citrus.dsl.junit.JUnit4CitrusTestRunner;
import com.consol.citrus.dsl.runner.TestRunner;
import com.consol.citrus.ws.client.WebServiceClient;

import cucumber.api.java.en.When;

@ContextConfiguration(classes = CitrusSpringConfig.class)
public class CitrusSteps extends JUnit4CitrusTestRunner {
    @CitrusFramework
    private Citrus citrus;

    @CitrusResource
    private TestRunner runner;

    @CitrusResource
    private TestContext context;

    @Autowired
    private WebServiceClient getQuote;

    @When("^I call getQuote with id \"([^\"]*)\"$")
    public void i_call_getquote_with_id(String quoteId) throws Throwable {
        context = citrus.createTestContext();

        String soappayload = "my payload (taken out for privacy purposes)";

        runner.soap(action -> action.client(getQuote)
                .send()
                .soapAction("getQuote")
                .payload(soappayload));

        runner.soap(action -> action.client(getQuote)
        .receive()
        .name("getQuoteResponseStoredMessage"));        

        //this bombs out on the context line with this: "com.consol.citrus.exceptions.CitrusRuntimeException: Unknown variable 'messageStoreGetQuoteResponse1'"
        runner.variable("messageStoreGetQuoteResponse1", "citrus:message(getQuoteResponseStoredMessage.payload())");
        runner.echo("First try: ${messageStoreGetQuoteResponse1}");
        String firstTry = context.getVariable("messageStoreGetQuoteResponse1");
        log.info("First Try java variable: " + firstTry);

        //this bombs out on the context line with this: "com.consol.citrus.exceptions.CitrusRuntimeException: Unknown variable 'messageStoreGetQuoteResponse2'"
        runner.createVariable("messageStoreGetQuoteResponse2", "citrus:message(getQuoteResponseStoredMessage.payload())");
        runner.echo("Second try: ${messageStoreGetQuoteResponse2}");
        String secondTry = context.getVariable("messageStoreGetQuoteResponse2");
        log.info("Second Try java variable: " + secondTry);

        //This stores the literal as the value - it doesn't store the message so it appears I can't use citrus functions within the context
        context.setVariable("messageStoreGetQuoteResponse3", "citrus:message(getQuoteResponseStoredMessage.payload())");
        String thirdTry = context.getVariable("messageStoreGetQuoteResponse3");
        log.info("Third Try java variable: " + thirdTry);

    }

}

一位聪明的同事想出了一个解决注射黄瓜无效的方法。

我替换了这两行:

@CitrusResource
private TestContext context;

用这些行代替:

TestContext testContext;
public TestContext getTestContext() {
    if (testContext == null) {
        runner.run(new AbstractTestAction() {
            @Override
            public void doExecute(TestContext context) {
                testContext = context;
            }
        });
    }
    return testContext;
}

然后在我想要上下文的步骤中,我可以使用上面的方法。在我的例子中,我想要我的消息响应,所以我能够使用它并确认响应现在在我的 java 变量中:

String responseXML = getTestContext().getMessageStore().getMessage("getQuoteResponseStoredMessage").getPayload(String.class);
log.info("Show response XML: " + responseXML);