SWS-632 - Create Server-Side testing framework

This commit is contained in:
Arjen Poutsma
2010-09-20 12:30:39 +00:00
parent 7ff820a91c
commit d1d4620b93
13 changed files with 383 additions and 5 deletions

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.xml.transform.TransformerObjectSupport;
/**
* @author Arjen Poutsma
*/
abstract class AbstractRequestCreator<T extends WebServiceMessage> extends TransformerObjectSupport
implements RequestCreator<T> {
public final T createRequest(WebServiceMessageFactory<? extends T> messageFactory) throws IOException {
T request = messageFactory.createWebServiceMessage();
doWithRequest(request);
return request;
}
protected abstract void doWithRequest(T request) throws IOException;
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.springframework.ws.WebServiceMessage;
/**
* Implementation of {@link org.springframework.ws.mock.client.ResponseCreator} that writes a {@link
* javax.xml.transform.Source} response.
*
* @author Arjen Poutsma
* @since 2.0
*/
class PayloadRequestCreator extends AbstractRequestCreator<WebServiceMessage> {
private final Source payload;
PayloadRequestCreator(Source payload) {
this.payload = payload;
}
@Override
protected void doWithRequest(WebServiceMessage request) throws IOException {
try {
transform(payload, request.getPayloadResult());
}
catch (TransformerException ex) {
throw new AssertionError("Could not transform request payload to message: " + ex.getMessage());
}
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
/**
* @author Arjen Poutsma
*/
public interface RequestCreator<T extends WebServiceMessage> {
/**
* Create a request.
*
* @param messageFactory the message that can be used to create responses
* @throws java.io.IOException in case of I/O errors
*/
T createRequest(WebServiceMessageFactory<? extends T> messageFactory) throws IOException;
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server;
/**
* @author Arjen Poutsma
*/
public interface ResponseActions {
/**
* Allows for further expectations to be set on the request.
*
* @return the request expectations
*/
ResponseActions andExpect(ResponseMatcher responseMatcher);
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
* @author Arjen Poutsma
* @since 2.0
*/
public interface ResponseMatcher<T extends WebServiceMessage> {
/**
* Matches the given response message against the expectations. Implementations typically make use of JUnit-based
* assertions.
*
* @param response the request message to make assertions on
* @throws IOException in case of I/O errors
* @throws AssertionError if expectations are not met
*/
void match(T response) throws IOException, AssertionError;
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server;
import java.io.IOException;
import javax.xml.transform.Source;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.xml.transform.ResourceSource;
/**
* @author Arjen Poutsma
*/
public abstract class WebServiceMock {
public static ResponseActions receiveMessage(RequestCreator requestCreator) {
return null;
}
public static RequestCreator withPayload(Source payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadRequestCreator(payload);
}
public static RequestCreator withPayload(Resource payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadRequestCreator(createResourceSource(payload));
}
public static ResponseMatcher payload(Source payload) {
return null;
}
/**
* Expects any request.
*
* @return the request matcher
*/
public static ResponseMatcher anything() {
return new ResponseMatcher() {
public void match(WebServiceMessage response) throws IOException, AssertionError {
}
};
}
private static ResourceSource createResourceSource(Resource resource) {
try {
return new ResourceSource(resource);
}
catch (IOException ex) {
throw new IllegalArgumentException(resource + " could not be opened", ex);
}
}
}

View File

@@ -22,6 +22,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.mock.integration.CustomerCountRequest;
import org.springframework.ws.mock.integration.CustomerCountResponse;
import org.springframework.xml.transform.StringSource;
import org.junit.Before;
@@ -39,7 +41,7 @@ import static org.springframework.ws.mock.client.WebServiceMock.*;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("integration-test.xml")
public class IntegrationTest {
public class ClientIntegrationTest {
@Autowired
private WebServiceTemplate webServiceTemplate;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ws.mock.client.integration;
package org.springframework.ws.mock.integration;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ws.mock.client.integration;
package org.springframework.ws.mock.integration;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server.integration;
import org.springframework.ws.mock.integration.CustomerCountRequest;
import org.springframework.ws.mock.integration.CustomerCountResponse;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
@Endpoint
public class CustomerEndpoint {
@ResponsePayload
public CustomerCountResponse getCustomerCount(@RequestPayload CustomerCountRequest request) {
CustomerCountResponse response = new CustomerCountResponse();
response.setCustomerCount(42);
return response;
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.mock.server.integration;
import javax.xml.transform.Source;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.xml.transform.StringSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.springframework.ws.mock.server.WebServiceMock.*;
/**
* @author Arjen Poutsma
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("integration-test.xml")
public class ServerIntegrationTest {
@Test
public void basic() throws Exception {
Source requestPayload = new StringSource("<customerCountRequest xmlns='http://springframework.org/client'>" +
"<customerName>John Doe</customerName>" + "</customerCountRequest>");
Source responsePayload = new StringSource("<customerCountResponse xmlns='http://springframework.org/client'>" +
"<customerCount>10</customerCount>" + "</customerCountResponse>");
receiveMessage(withPayload(requestPayload)).andExpect(payload(responsePayload));
}
}

View File

@@ -12,8 +12,8 @@
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.springframework.ws.mock.client.integration.CustomerCountRequest</value>
<value>org.springframework.ws.mock.client.integration.CustomerCountResponse</value>
<value>org.springframework.ws.mock.integration.CustomerCountRequest</value>
<value>org.springframework.ws.mock.integration.CustomerCountResponse</value>
</list>
</property>
</bean>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="http://example.com"/>
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.springframework.ws.mock.integration.CustomerCountRequest</value>
<value>org.springframework.ws.mock.integration.CustomerCountResponse</value>
</list>
</property>
</bean>
</beans>