0

跟进我可以在 Citrus 静态响应适配器有效负载中使用 Citrus 变量吗?

我正在使用 Citrus 2.7,我的测试扩展了 TestNGCitrusTestRunner:

@Test
@CitrusTest
public void testRequestOk() {
    variable("myTest", "baz");

    http(builder -> builder
        .client("fooClient")
        .send()
        .post("/foo/bar")
        .payload(new ClassPathResource("/foo/bar-baz.xml"))
        .messageType(MessageType.XML)
        .contentType("application/xml")
        .accept("application/xml"));

    http(builder -> builder
        .client("fooClient")
        .receive()
        .response(HttpStatus.OK)
        .validate("foo.bar", "baz"));
}

该请求被发送到 SUT,SUT 进而触发对 Citrus 的两个 http 调用(对 mockOne 和 mockTwo)。

使用以下配置:

<citrus-http:server id="mockOne"
                    port="9090"
                    auto-start="true"
                    endpoint-adapter="staticResponseAdapter"
                    security-handler="securityHandlerOne"/>

<citrus-http:server id="mockTwo"
                    port="9080"
                    auto-start="true"
                    endpoint-adapter="dispatchingEndpointAdapter"
                    security-handler="securityHandlerTwo"/>

...

<citrus:static-response-adapter id="staticResponseAdapter">
    <citrus:payload>
        <![CDATA[
        <?xml version="1.0" encoding="UTF-8"?>
        <foo>
            <bar>${myTest}</bar>
        </foo>
        ]]>
    </citrus:payload>
</citrus:static-response-adapter>

我收到:com.consol.citrus.exceptions.CitrusRuntimeException: Unknown variable 'myTest'

在日志中,我看到最初设置了变量:

15:02:48,696 DEBUG        citrus.Citrus| TEST STEP 1: create-variables
15:02:48,697 INFO  reateVariablesAction| Setting variable: myTest to value: foo
15:02:48,697 DEBUG  context.TestContext| Setting variable: myTest with value: 'foo'

但是在变量替换发生之前,Citrus 会这样做:

15:02:49,281 DEBUG ngHandlerInterceptor| Received Http request:
...
15:02:49,297 DEBUG t.TestContextFactory| Created new test context - using global variables: '{}'
15:02:49,299 DEBUG rusDispatcherServlet| Could not complete request
com.consol.citrus.exceptions.CitrusRuntimeException: Unknown variable 'myTest'

我做错了什么还是这是预期的行为?

4

1 回答 1

0

这是静态响应适配器创建自己的测试上下文时的预期行为。你可以在日志中看到

15:02:49,297 DEBUG t.TestContextFactory| Created new test context - using global variables: '{}'

因此,通常静态响应适配器无法访问您的测试实例的测试变量。这仅仅是因为传入请求与您正在运行的测试没有可能的关联。这就是描述“静态”响应适配器中的“静态”响应的内容。

如果您希望获得更多动态响应消息,您应该在测试中使用http(builder -> builder.server("mockOne").receive())和包含服务器通信http(builder -> builder.server("mockOne").send().response())

然后,您可以使用测试行为 ( http://www.citrusframework.org/reference/html/behaviors.html ) 而不是静态响应适配器。这样,您只需定义一次服务器通信并在多个测试中使用它。

public class MockOneServerBehavior extends AbstractTestBehavior {
    public void apply() {
        http(builder -> builder.server("mockOne")
                               .receive()
                               .post());

        http(builder -> builder.server("mockOne")
                               .send()
                               .response()
                               .payload("<foo><bar>${myTest}</bar></foo>"));
    }
}

当行为明确应用于您的测试时,该行为能够访问您的测试的测试变量。

@Test
@CitrusTest
public void testRequestOk() {
    variable("myTest", "baz");

    http(builder -> builder
        .client("fooClient")
        .send()
        .post("/foo/bar")
        .payload(new ClassPathResource("/foo/bar-baz.xml"))
        .messageType(MessageType.XML)
        .contentType("application/xml")
        .accept("application/xml"))
        .fork(true);

    MockOneServerBehavior mockOneBehavior = new MockOneServerBehavior();
    applyBehavior(mockOneBehavior);

    http(builder -> builder
        .client("fooClient")
        .receive()
        .response(HttpStatus.OK)
        .validate("foo.bar", "baz"));
}

请注意,我在 http 客户端发送操作中添加了一个fork选项。这是因为 Http 协议本质上是同步的,Citrus 同时充当客户端和服务器。

于 2017-02-27T07:36:02.213 回答