Functional tests

In this tutorial we will cover support for functional tests. By a functional test we mean a test, that is not executed by a Java code but by hand, by a tool like Selenium or by some other tool. In such cases, it's not possible to use our unit test support. We need something more similar to a mock server.

So let's say that we have our code finished and it generates the following request.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
        <SOAP-ENV:Header />
        <SOAP-ENV:Body>
                <ns3:GetFlightsRequest
                        xmlns:ns2="http://www.springframework.org/spring-ws/samples/airline/schemas/types"
                        xmlns:ns3="http://www.springframework.org/spring-ws/samples/airline/schemas/messages">
                        <ns3:from>PRG</ns3:from>
                        <ns3:to>DUB</ns3:to>
                        <ns3:departureDate>2009-10-31+01:00</ns3:departureDate>
                        <ns3:serviceClass>economy</ns3:serviceClass>
                </ns3:GetFlightsRequest>
        </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

We need to configure the application so the request is validated and a mock response is returned.

Mock response structure

We can start by creating mock responses. To do this we have to create a special directory structure in our classpath. If you are using Maven, the ideal place to create it is in src/test/resources. Default directory name where mock responses are looked for is "mock-xml/payloadRootName". For example, if your WS message payload root element is called "GetFlightsRequest", resources from "mock-xml/GetFlightsRequest" are used.

"response.xml" file is used as template for generating response, if not specified otherwise.

Of course, only one mock response per service is not sufficient. It is usually needed to define more response files. To be able to do this, it has to be defined a way how to decide which file will be used. By default XPath discriminators are used. For example, if "//ns:from;//ns:to" is used as discriminators for given service and our sample request is used, content of "mock-xml/GetFlightsRequest/PRG-DUB-response.xml" will be returned as a mock response. If this file is not found "mock-xml/GetFlightsRequest/PRG-response.xml" will be used and if even that file is not found, default response will be returned.

Configuration file

Usual configuration will look like the following example.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:swst="http://javacrumbs.net/schema/1.0/spring-ws-test"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                http://javacrumbs.net/schema/1.0/spring-ws-test http://javacrumbs.net/schema/1.0/spring-ws-test.xsd
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

        <swst:mock-ws-message-sender>
                <swst:namespaces>
                        <entry key="ns" value="http://www.springframework.org/spring-ws/samples/airline/schemas/messages"/>
                </swst:namespaces>
                <swst:resource-config>
                        <swst:discriminators>
                                <entry key="GetFlightsRequest" value="//ns:from;//ns:to"/>
                        </swst:discriminators>          
                </swst:resource-config>
                <swst:schemas>
                                xsd/messages.xsd
                                xsd/types.xsd
                </swst:schemas>
        </swst:mock-ws-message-sender>
</beans>

When this configuration will be loaded by Spring a mock message sender will be created and automatically injected into the WebServiceTemplate. Default WebServiceMessageSender will be replaced by the mock. Please note that WebServiceTemplate is not defined here, you probably have it already defined in another configuration file.

Test

When you have the configuration and mock response, you can start writing the test. The only thing you need to do is to load "dummy-message-sender.xml" together with the rest of your Spring configuration files.

Validation

If you want to validate your request you can either define schemas or it is also possible to compare request with predefined templates. The only thing you have to do is to create file "PRG-DUB-request.xml" in the same directory and the request will be automatically compared to the content of the file.

Templates

It is also possible to use XSLT templates for both response generation and request validation. Please consult reference for more details.