How to access variables in a (citrus) static-response-adapter

夙愿已清 提交于 2019-12-25 09:16:40

问题


Following up on Can I use Citrus variable in Citrus static response adapter payload?

I am using Citrus 2.7 and my test extends 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"));
}

The request is sent to the SUT, which in turn triggers two http calls to Citrus (to mockOne and mockTwo).

with the following config:

<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>

I receive: com.consol.citrus.exceptions.CitrusRuntimeException: Unknown variable 'myTest'

In the logs, I see that intially the variable is set:

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'

But right before the variable substitution should occur, Citrus does this:

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'

Am I doing something wrong or is this the expected behavior?


回答1:


This is the expected behavior as the static response adapter creates its own test context. You can see that in logs

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

So in general the static response adapter is not able to access the test variables of your test instance. This is simply because there is no possible correlation of incoming request to your running test. This is what describes the "static" response in "static" response adapter.

In case you want to have more dynamic response messages you should include the server communication in your test with http(builder -> builder.server("mockOne").receive()) and http(builder -> builder.server("mockOne").send().response()).

You can use test behaviors (http://www.citrusframework.org/reference/html/behaviors.html) instead of static response adapter then. This way you define that server communication once and use it in several tests.

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>"));
    }
}

The behavior is able to access the test variables of your test as the behavior gets explicitly applied in your test.

@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"));
}

Please notice that I have added a fork option to the http client send operation. This is because Http protocol is synchronous by nature and Citrus is acting as client and server simultaneously.



来源:https://stackoverflow.com/questions/42394035/how-to-access-variables-in-a-citrus-static-response-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!