javacitrus-framework

Citrus-Framework: Conditional validation depending on status code


I'm evaluating citrus-framework for blackbox testing of a rest service.

is there a way with the java DSL and the conditional container todo a validation depending of status code?

       http(httpActionBuilder -> httpActionBuilder
                .client(sutClient)
                .receive()
                .response()
                .messageType(MessageType.JSON)
                .extractFromPayload("$.", "operationReponse")
                .extractFromHeader(HttpMessageHeaders.HTTP_STATUS_CODE, "statusCode"));

        conditional().when("${statusCode} = 200").actions(
                // how to validate on ${operationResponse} ??
                .validate("$.field1", "${expectedUUID}")
                .validate("$.elements[0].result", "APPROVED")
        );

        conditional().when("${statusCode} = 301").actions(
                // how to extract from a variable ${operationResponse}  ?? 
                extractFromPayload("$.pollUrl", "idToGet");
                http(hab -> hab.client(sutClient).send().get("/v1/myendpoint"));
                http(hab -> hab.client(sutClient).receive().response(HttpStatus.OK)
                .messageType(MessageType.JSON)
                .validate("$.field1", "${expectedUUID}")
                .validate("$.elements[0].result", "APPROVED")

        );

eventually would like to create a behavior for reuse on different test cases.


Solution

  • What you need here is to store the received Http response into the local message store for later validation. Instead of extracting the payload to a variable you can add a name for the received message:

    http(httpActionBuilder -> httpActionBuilder
                    .client(sutClient)
                    .receive()
                    .response()
                    .messageType(MessageType.JSON)
                    .name("operationResponse")
                    .extractFromHeader(HttpMessageHeaders.HTTP_STATUS_CODE, "statusCode"));
    

    You can access the named message content later in further test steps then.

    echo("citrus:message(helloMessage.payload())")
    

    For more complex logic I would add a custom test action and access the message store to load the message by its name:

    action(new AbstractTestAction() {
        @Override
        public void doExecute(TestContext context) {
            // do something with stored message
            Message message = context.getMessageStore().getMessage("operationResponse"); 
        }
    })
    

    By the way I have spotted a typo in your sample code where you use "operationReponse" and "operationResponse".