SWS-544 - Add test framework for Spring WS client

This commit is contained in:
Arjen Poutsma
2010-07-09 12:48:25 +00:00
parent f770046c99
commit 33ec9eedb6
23 changed files with 1622 additions and 0 deletions

View File

@@ -49,5 +49,9 @@
<artifactId>xmlunit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,60 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import org.springframework.ws.WebServiceMessage;
import org.springframework.xml.transform.TransformerObjectSupport;
import org.custommonkey.xmlunit.Diff;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.custommonkey.xmlunit.XMLAssert.fail;
/**
* Implementation of {@link RequestMatcher} based on XMLUnit's {@link Diff}.
*
* @author Arjen Poutsma
* @since 2.0
*/
abstract class DiffMatcher extends TransformerObjectSupport implements RequestMatcher {
public final void match(URI uri, WebServiceMessage request) throws IOException, AssertionError {
try {
Diff diff = createDiff(request);
assertXMLEqual(diff, true);
}
catch (IOException ex) {
throw ex;
}
catch (Exception ex) {
fail("Could not create Diff: " + ex.getMessage());
}
}
/**
* Creates a {@link org.custommonkey.xmlunit.Diff} for the given request message.
*
* @param request the request message
* @return the diff
* @throws Exception in case of errors
*/
protected abstract Diff createDiff(WebServiceMessage request) throws Exception;
}

View File

@@ -0,0 +1,45 @@
/*
* 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.client2;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
* Implementation of {@link ResponseCallback} that holds an error message.
*
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
class ErrorResponseCallback implements ResponseCallback {
private final String errorMessage;
ErrorResponseCallback(String errorMessage) {
this.errorMessage = errorMessage;
}
public void doWithResponse(WebServiceMessage response, WebServiceMessage request) throws IOException {
// Do nothing
}
String getErrorMessage() {
return errorMessage;
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.client2;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
* Implementation of {@link ResponseCallback} that responds by throwing either an {@link IOException} or a {@link
* RuntimeException}.
*
* @author Arjen Poutsma
* @since 2.0
*/
class ExceptionResponseCallback implements ResponseCallback {
private final Exception exception;
ExceptionResponseCallback(IOException exception) {
this.exception = exception;
}
ExceptionResponseCallback(RuntimeException exception) {
this.exception = exception;
}
public void doWithResponse(WebServiceMessage request, WebServiceMessage response) throws IOException {
if (exception instanceof IOException) {
throw (IOException) exception;
}
else {
throw (RuntimeException) exception;
}
}
}

View File

@@ -0,0 +1,135 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
/**
* Mock implementation of {@link FaultAwareWebServiceConnection}. Implements {@link ResponseActions} to form a fluent
* API.
*
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
class MockSenderConnection implements FaultAwareWebServiceConnection, ResponseActions {
private final List<RequestMatcher> requestMatchers = new LinkedList<RequestMatcher>();
private URI uri;
private boolean lastConnection = false;
private WebServiceMessage request;
private ResponseCallback responseCallback;
void addRequestMatcher(RequestMatcher requestMatcher) {
Assert.notNull(requestMatcher, "'requestMatcher' must not be null");
requestMatchers.add(requestMatcher);
}
void setUri(URI uri) {
Assert.notNull(uri, "'uri' must not be null");
this.uri = uri;
}
void lastConnection() {
lastConnection = true;
}
// ResponseActions implementation
public ResponseActions andExpect(RequestMatcher requestMatcher) {
addRequestMatcher(requestMatcher);
return this;
}
public void andRespond(ResponseCallback responseCallback) {
Assert.notNull(responseCallback, "'responseCallback' must not be null");
this.responseCallback = responseCallback;
}
// FaultAwareWebServiceConnection implementation
public void send(WebServiceMessage message) throws IOException {
if (!requestMatchers.isEmpty()) {
for (RequestMatcher requestMatcher : requestMatchers) {
requestMatcher.match(uri, message);
}
}
else {
throw new AssertionError("Unexpected send() for [" + message + "]");
}
this.request = message;
}
public WebServiceMessage receive(WebServiceMessageFactory messageFactory) throws IOException {
if (responseCallback != null) {
WebServiceMessage response = messageFactory.createWebServiceMessage();
responseCallback.doWithResponse(request, response);
return response;
}
else {
return null;
}
}
public URI getUri() {
return uri;
}
public boolean hasError() throws IOException {
return responseCallback instanceof ErrorResponseCallback;
}
public String getErrorMessage() throws IOException {
if (responseCallback instanceof ErrorResponseCallback) {
return ((ErrorResponseCallback) responseCallback).getErrorMessage();
}
else {
return null;
}
}
public boolean hasFault() throws IOException {
return responseCallback instanceof SoapFaultResponseCallback;
}
public void setFault(boolean fault) throws IOException {
// Do nothing
}
public void close() throws IOException {
requestMatchers.clear();
request = null;
responseCallback = null;
uri = null;
if (lastConnection) {
MockWebServiceMessageSenderHolder.clear();
}
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.ws.transport.WebServiceMessageSender;
import static org.junit.Assert.assertTrue;
class MockWebServiceMessageSender implements WebServiceMessageSender {
private final List<MockSenderConnection> expectedConnections = new LinkedList<MockSenderConnection>();
private Iterator<MockSenderConnection> connectionIterator;
public MockSenderConnection createConnection(URI uri) throws IOException {
Assert.notNull(uri, "'uri' must not be null");
if (connectionIterator == null) {
connectionIterator = expectedConnections.iterator();
}
assertTrue("No further connections expected", connectionIterator.hasNext());
MockSenderConnection currentConnection = connectionIterator.next();
currentConnection.setUri(uri);
if (!connectionIterator.hasNext()) {
currentConnection.lastConnection();
}
return currentConnection;
}
/** Always returns {@code true}. */
public boolean supports(URI uri) {
return true;
}
MockSenderConnection expectNewConnection() {
MockSenderConnection connection = new MockSenderConnection();
expectedConnections.add(connection);
return connection;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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.client2;
import org.springframework.core.NamedThreadLocal;
/**
* @author Arjen Poutsma
* @since 2.0
*/
class MockWebServiceMessageSenderHolder {
private static final NamedThreadLocal<MockWebServiceMessageSender> mockWebServiceMessageSenderHolder =
new NamedThreadLocal<MockWebServiceMessageSender>("Mock Message Sender");
/** Associate the given {@link MockWebServiceMessageSender} with the current thread. */
public static void set(MockWebServiceMessageSender messageSender) {
mockWebServiceMessageSenderHolder.set(messageSender);
}
/** Return the {@link MockWebServiceMessageSender} associated with the current thread, if any. */
public static MockWebServiceMessageSender get() {
return mockWebServiceMessageSenderHolder.get();
}
/**
* Clears the holder.
*/
public static void clear() {
set(null);
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.client2;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.custommonkey.xmlunit.Diff;
import org.w3c.dom.Document;
import static junit.framework.Assert.fail;
/**
* Matches {@link Source} payloads.
*
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
class PayloadMatcher extends DiffMatcher {
private final Source expected;
PayloadMatcher(Source expected) {
Assert.notNull(expected, "'expected' must not be null");
this.expected = expected;
}
@Override
protected final Diff createDiff(WebServiceMessage request) throws Exception {
Source payload = request.getPayloadSource();
if (payload == null) {
fail("Request message does not contain payload");
}
return createDiff(payload);
}
protected Diff createDiff(Source payload) throws TransformerException {
Document expectedDocument = createDocumentFromSource(expected);
Document actualDocument = createDocumentFromSource(payload);
return new Diff(expectedDocument, actualDocument);
}
private Document createDocumentFromSource(Source source) throws TransformerException {
DOMResult result = new DOMResult();
transform(source, result);
return (Document) result.getNode();
}
}

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.client2;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.springframework.ws.WebServiceMessage;
import org.springframework.xml.transform.TransformerObjectSupport;
/**
* Implementation of {@link ResponseCallback} that writes a {@link Source} response.
*
* @author Arjen Poutsma
* @since 2.0
*/
class PayloadResponseCallback extends TransformerObjectSupport implements ResponseCallback {
private final Source payload;
PayloadResponseCallback(Source payload) {
this.payload = payload;
}
public void doWithResponse(WebServiceMessage request, WebServiceMessage response) throws IOException {
try {
transform(payload, response.getPayloadResult());
}
catch (TransformerException ex) {
throw new AssertionError("Could not transform response payload to message: " + ex.getMessage());
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import org.springframework.ws.WebServiceMessage;
/**
* Defines the contract for matching requests to expectations.
*
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
public interface RequestMatcher {
/**
* Matches the given request message against the expectations. Implementations typically make use of JUnit-based
* assertions.
*
* @param uri the uri connected to
* @param request the request message to make assertions on
* @throws IOException in case of I/O errors
* @throws AssertionError if expectations are not met
*/
void match(URI uri, WebServiceMessage request) throws IOException, AssertionError;
}

View File

@@ -0,0 +1,41 @@
/*
* 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.client2;
/**
* Allows for setting up responses. Implementations of this interface are returned by {@link WebServiceMock}.
*
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
public interface ResponseActions {
/**
* Allows for further expectations to be set on the request.
*
* @return the request expectations
*/
ResponseActions andExpect(RequestMatcher requestMatcher);
/**
* Sets the {@link ResponseCallback} for this mock.
*
* @param responseCallback the response callback
*/
void andRespond(ResponseCallback responseCallback);
}

View File

@@ -0,0 +1,42 @@
/*
* 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.client2;
import java.io.IOException;
import org.springframework.ws.WebServiceMessage;
/**
* Callback interface for code that operates on response {@link org.springframework.ws.WebServiceMessage}s. Defines the contract for creating
* responses in test scenarios.
*
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
public interface ResponseCallback {
/**
* Execute any number of operations on the supplied response, given the request.
*
* @param request the request message
* @param response the response message
* @throws java.io.IOException in case of I/O errors
*/
void doWithResponse(WebServiceMessage request, WebServiceMessage response) throws IOException;
}

View File

@@ -0,0 +1,95 @@
/*
* 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.client2;
import java.io.IOException;
import java.util.Locale;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapBody;
import org.springframework.ws.soap.SoapMessage;
import static org.junit.Assert.fail;
/**
* Implementation of {@link ResponseCallback} that responds with a SOAP fault.
*
* @author Arjen Poutsma
* @since 2.0
*/
abstract class SoapFaultResponseCallback implements ResponseCallback {
public final void doWithResponse(WebServiceMessage request, WebServiceMessage response) throws IOException {
if (!(response instanceof SoapMessage)) {
fail("Response message is not a SOAP message");
return;
}
SoapMessage soapResponse = (SoapMessage) response;
SoapBody soapResponseBody = soapResponse.getSoapBody();
if (soapResponseBody == null) {
fail("SOAP message [" + soapResponse + "] does not contain SOAP body");
}
addSoapFault(soapResponseBody);
}
public abstract void addSoapFault(SoapBody soapBody);
public static SoapFaultResponseCallback createMustUnderstandFault(final String faultStringOrReason,
final Locale locale) {
return new SoapFaultResponseCallback() {
@Override
public void addSoapFault(SoapBody soapBody) {
soapBody.addMustUnderstandFault(faultStringOrReason, locale);
}
};
}
public static SoapFaultResponseCallback createClientOrSenderFault(final String faultStringOrReason,
final Locale locale) {
return new SoapFaultResponseCallback() {
@Override
public void addSoapFault(SoapBody soapBody) {
soapBody.addClientOrSenderFault(faultStringOrReason, locale);
}
};
}
public static SoapFaultResponseCallback createServerOrReceiverFault(final String faultStringOrReason,
final Locale locale) {
return new SoapFaultResponseCallback() {
@Override
public void addSoapFault(SoapBody soapBody) {
soapBody.addServerOrReceiverFault(faultStringOrReason, locale);
}
};
}
public static SoapFaultResponseCallback createVersionMismatchFault(final String faultStringOrReason,
final Locale locale) {
return new SoapFaultResponseCallback() {
@Override
public void addSoapFault(SoapBody soapBody) {
soapBody.addVersionMismatchFault(faultStringOrReason, locale);
}
};
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import java.util.Iterator;
import javax.xml.namespace.QName;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Matches SOAP headers.
*
* @author Arjen Poutsma
* @since 2.0
*/
class SoapHeaderMatcher implements RequestMatcher {
private final QName soapHeaderName;
SoapHeaderMatcher(QName soapHeaderName) {
this.soapHeaderName = soapHeaderName;
}
public void match(URI uri, WebServiceMessage request) throws IOException, AssertionError {
if (!(request instanceof SoapMessage)) {
fail("Request message is not a SOAP message");
return;
}
SoapMessage soapMessage = (SoapMessage) request;
SoapHeader soapHeader = soapMessage.getSoapHeader();
if (soapHeader == null) {
fail("SOAP message [" + soapMessage + "] does not contain SOAP header");
}
Iterator<SoapHeaderElement> soapHeaderElementIterator = soapHeader.examineAllHeaderElements();
boolean found = false;
while (soapHeaderElementIterator.hasNext()) {
SoapHeaderElement soapHeaderElement = soapHeaderElementIterator.next();
if (soapHeaderName.equals(soapHeaderElement.getName())) {
found = true;
break;
}
}
assertTrue("SOAP header [" + soapHeaderName + "] not found", found);
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.client2;
import java.net.URI;
import org.springframework.ws.WebServiceMessage;
import static org.junit.Assert.assertEquals;
/**
* Matches {@link URI}s.
*
* @author Arjen Poutsma
* @since 2.0
*/
class UriMatcher implements RequestMatcher {
private final URI expected;
UriMatcher(URI expected) {
this.expected = expected;
}
public void match(URI actual, WebServiceMessage request) {
assertEquals("Unexpected connection", expected, actual);
}
}

View File

@@ -0,0 +1,259 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import java.util.Locale;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.xml.transform.ResourceSource;
import org.springframework.xml.transform.StringSource;
/**
* @author Arjen Poutsma
* @author Lukas Krecan
* @since 2.0
*/
public abstract class WebServiceMock {
public static void mockWebServiceTemplate(WebServiceTemplate webServiceTemplate) {
Assert.notNull(webServiceTemplate, "'webServiceTemplate' must not be null");
MockWebServiceMessageSender mockMessageSender = new MockWebServiceMessageSender();
webServiceTemplate.setMessageSender(mockMessageSender);
MockWebServiceMessageSenderHolder.set(mockMessageSender);
}
/**
* Records an expectation specified by the given {@link RequestMatcher}. Returns a {@link ResponseActions} object
* that allows for setting up the response, or more expectations.
*
* @param requestMatcher the request matcher expected
* @return the response actions
*/
public static ResponseActions expect(RequestMatcher requestMatcher) {
MockWebServiceMessageSender messageSender = MockWebServiceMessageSenderHolder.get();
Assert.state(messageSender != null,
"WebServiceTemplate has not been mocked. Did you call mockWebServiceTemplate() ?");
MockSenderConnection connection = messageSender.expectNewConnection();
connection.addRequestMatcher(requestMatcher);
return connection;
}
// RequestMatchers
/**
* Expects the given String XML payload.
*
* @param payload the XML payload
* @return the request matcher
*/
public static RequestMatcher payload(String payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadMatcher(new StringSource(payload));
}
/**
* Expects the given {@link Source} XML payload.
*
* @param payload the XML payload
* @return the request matcher
*/
public static RequestMatcher payload(Source payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadMatcher(payload);
}
/**
* Expects the given {@link Resource} XML payload.
*
* @param payload the XML payload
* @return the request matcher
*/
public static RequestMatcher payload(Resource payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadMatcher(createResourceSource(payload));
}
/**
* Expects the given SOAP header in the outgoing message.
*
* @param soapHeaderName the qualified name of the SOAP header to expect
* @return the request matcher
*/
public static RequestMatcher soapHeader(QName soapHeaderName) {
Assert.notNull(soapHeaderName, "'soapHeaderName' must not be null");
return new SoapHeaderMatcher(soapHeaderName);
}
/**
* Expects a connection to the given URI.
*
* @param uri the String uri expected to connect to
* @return the request matcher
*/
public static RequestMatcher connectionTo(String uri) {
Assert.notNull(uri, "'uri' must not be null");
return connectionTo(URI.create(uri));
}
/**
* Expects a connection to the given URI.
*
* @param uri the String uri expected to connect to
* @return the request matcher
*/
public static RequestMatcher connectionTo(URI uri) {
Assert.notNull(uri, "'uri' must not be null");
return new UriMatcher(uri);
}
// ResponseCallbacks
/**
* Respond with the given String XML as payload response.
*
* @param payload the response payload
* @return the response callback
*/
public static ResponseCallback withPayload(String payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadResponseCallback(new StringSource(payload));
}
/**
* Respond with the given {@link Source} XML as payload response.
*
* @param payload the response payload
* @return the response callback
*/
public static ResponseCallback withPayload(Source payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadResponseCallback(payload);
}
/**
* Respond with the given {@link Resource} XML as payload response.
*
* @param payload the response payload
* @return the response callback
*/
public static ResponseCallback withPayload(Resource payload) {
Assert.notNull(payload, "'payload' must not be null");
return new PayloadResponseCallback(createResourceSource(payload));
}
/**
* Respond with an error.
*
* @param errorMessage the error message
* @return the response callback
* @see org.springframework.ws.transport.WebServiceConnection#hasError()
* @see org.springframework.ws.transport.WebServiceConnection#getErrorMessage()
*/
public static ResponseCallback withError(String errorMessage) {
Assert.hasLength(errorMessage, "'errorMessage' must not be empty");
return new ErrorResponseCallback(errorMessage);
}
/**
* Respond with an {@link IOException}.
*
* @param ioException the exception to be thrown
* @return the response callback
*/
public static ResponseCallback withException(IOException ioException) {
Assert.notNull(ioException, "'ioException' must not be null");
return new ExceptionResponseCallback(ioException);
}
/**
* Respond with an {@link RuntimeException}.
*
* @param ex the runtime exception to be thrown
* @return the response callback
*/
public static ResponseCallback withException(RuntimeException ex) {
Assert.notNull(ex, "'ex' must not be null");
return new ExceptionResponseCallback(ex);
}
/**
* Respond with a {@code MustUnderstand} fault.
*
* @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text
* @param locale the language of faultStringOrReason. Optional for SOAP 1.1
* @see org.springframework.ws.soap.SoapBody#addMustUnderstandFault(String, Locale)
*/
public static ResponseCallback withMustUnderstandFault(String faultStringOrReason, Locale locale) {
Assert.hasLength(faultStringOrReason, "'faultStringOrReason' must not be empty");
return SoapFaultResponseCallback.createMustUnderstandFault(faultStringOrReason, locale);
}
/**
* Respond with a {@code Client} (SOAP 1.1) or {@code Sender} (SOAP 1.2) fault.
*
* @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text
* @param locale the language of faultStringOrReason. Optional for SOAP 1.1
* @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
*/
public static ResponseCallback withClientOrSenderFault(String faultStringOrReason, Locale locale) {
Assert.hasLength(faultStringOrReason, "'faultStringOrReason' must not be empty");
return SoapFaultResponseCallback.createClientOrSenderFault(faultStringOrReason, locale);
}
/**
* Respond with a {@code Server} (SOAP 1.1) or {@code Receiver} (SOAP 1.2) fault.
*
* @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text
* @param locale the language of faultStringOrReason. Optional for SOAP 1.1
* @see org.springframework.ws.soap.SoapBody#addServerOrReceiverFault(String, Locale)
*/
public static ResponseCallback withServerOrReceiverFault(String faultStringOrReason, Locale locale) {
Assert.hasLength(faultStringOrReason, "'faultStringOrReason' must not be empty");
return SoapFaultResponseCallback.createServerOrReceiverFault(faultStringOrReason, locale);
}
/**
* Respond with a {@code VersionMismatch} fault.
*
* @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text
* @param locale the language of faultStringOrReason. Optional for SOAP 1.1
* @see org.springframework.ws.soap.SoapBody#addVersionMismatchFault(String, Locale)
*/
public static ResponseCallback withVersionMismatchFault(String faultStringOrReason, Locale locale) {
Assert.hasLength(faultStringOrReason, "'faultStringOrReason' must not be empty");
return SoapFaultResponseCallback.createVersionMismatchFault(faultStringOrReason, locale);
}
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

@@ -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.client2;
import java.io.IOException;
import org.junit.Test;
public class ExceptionResponseCallbackTest {
@Test(expected = IOException.class)
public void ioException() throws Exception {
ExceptionResponseCallback callback = new ExceptionResponseCallback(new IOException());
callback.doWithResponse(null, null);
}
@Test(expected = RuntimeException.class)
public void runtimeException() throws Exception {
ExceptionResponseCallback callback = new ExceptionResponseCallback(new RuntimeException());
callback.doWithResponse(null, null);
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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.client2;
import org.springframework.ws.WebServiceMessage;
import org.springframework.xml.transform.StringSource;
import org.junit.Test;
import static org.easymock.EasyMock.*;
public class PayloadMatcherTest {
@Test
public void match() throws Exception {
String xml = "<element xmlns='http://example.com'/>";
WebServiceMessage message = createMock(WebServiceMessage.class);
expect(message.getPayloadSource()).andReturn(new StringSource(xml));
replay(message);
PayloadMatcher matcher = new PayloadMatcher(new StringSource(xml));
matcher.match(null, message);
verify(message);
}
@Test(expected = AssertionError.class)
public void nonMatch() throws Exception {
String actual = "<element1 xmlns='http://example.com'/>";
WebServiceMessage message = createMock(WebServiceMessage.class);
expect(message.getPayloadSource()).andReturn(new StringSource(actual));
replay(message);
String expected = "<element2 xmlns='http://example.com'/>";
PayloadMatcher matcher = new PayloadMatcher(new StringSource(expected));
matcher.match(null, message);
}
}

View File

@@ -0,0 +1,107 @@
/*
* 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.client2;
import java.io.IOException;
import java.util.Locale;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.SoapVersion;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.soap11.Soap11Fault;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SoapFaultResponseCallbackTest {
private SoapMessage response;
@Before
public void createResponse() throws SOAPException {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage saajResponse = messageFactory.createMessage();
this.response = new SaajSoapMessage(saajResponse);
}
@Test
public void clientOrSenderFault() throws IOException {
String faultString = "Foo";
SoapFaultResponseCallback callback = SoapFaultResponseCallback.createClientOrSenderFault(faultString, Locale.ENGLISH);
callback.doWithResponse(null, response);
assertTrue("Response has no fault", response.hasFault());
Soap11Fault soapFault = (Soap11Fault) response.getSoapBody().getFault();
assertEquals("Response has invalid fault code", SoapVersion.SOAP_11.getClientOrSenderFaultName(),
soapFault.getFaultCode());
assertEquals("Response has invalid fault string", faultString, soapFault.getFaultStringOrReason());
assertEquals("Response has invalid fault locale", Locale.ENGLISH, soapFault.getFaultStringLocale());
}
@Test
public void mustUnderstandFault() throws IOException {
String faultString = "Foo";
SoapFaultResponseCallback callback = SoapFaultResponseCallback.createMustUnderstandFault(faultString, Locale.ENGLISH);
callback.doWithResponse(null, response);
assertTrue("Response has no fault", response.hasFault());
Soap11Fault soapFault = (Soap11Fault) response.getSoapBody().getFault();
assertEquals("Response has invalid fault code", SoapVersion.SOAP_11.getMustUnderstandFaultName(),
soapFault.getFaultCode());
assertEquals("Response has invalid fault string", faultString, soapFault.getFaultStringOrReason());
assertEquals("Response has invalid fault locale", Locale.ENGLISH, soapFault.getFaultStringLocale());
}
@Test
public void serverOrReceiverFault() throws IOException {
String faultString = "Foo";
SoapFaultResponseCallback callback = SoapFaultResponseCallback.createServerOrReceiverFault(faultString, Locale.ENGLISH);
callback.doWithResponse(null, response);
assertTrue("Response has no fault", response.hasFault());
Soap11Fault soapFault = (Soap11Fault) response.getSoapBody().getFault();
assertEquals("Response has invalid fault code", SoapVersion.SOAP_11.getServerOrReceiverFaultName(),
soapFault.getFaultCode());
assertEquals("Response has invalid fault string", faultString, soapFault.getFaultStringOrReason());
assertEquals("Response has invalid fault locale", Locale.ENGLISH, soapFault.getFaultStringLocale());
}
@Test
public void versionMismatchFault() throws IOException {
String faultString = "Foo";
SoapFaultResponseCallback callback = SoapFaultResponseCallback.createVersionMismatchFault(faultString, Locale.ENGLISH);
callback.doWithResponse(null, response);
assertTrue("Response has no fault", response.hasFault());
Soap11Fault soapFault = (Soap11Fault) response.getSoapBody().getFault();
assertEquals("Response has invalid fault code", SoapVersion.SOAP_11.getVersionMismatchFaultName(),
soapFault.getFaultCode());
assertEquals("Response has invalid fault string", faultString, soapFault.getFaultStringOrReason());
assertEquals("Response has invalid fault locale", Locale.ENGLISH, soapFault.getFaultStringLocale());
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.client2;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.junit.Before;
import org.junit.Test;
import static org.easymock.EasyMock.createMock;
public class SoapHeaderMatcherTest {
private SoapHeaderMatcher matcher;
private QName expectedHeaderName;
@Before
public void setUp() throws Exception {
expectedHeaderName = new QName("http://example.com", "header");
matcher = new SoapHeaderMatcher(expectedHeaderName);
}
@Test
public void match() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage saajMessage = messageFactory.createMessage();
saajMessage.getSOAPHeader().addHeaderElement(expectedHeaderName);
SoapMessage soapMessage = new SaajSoapMessage(saajMessage);
matcher.match(null, soapMessage);
}
@Test(expected = AssertionError.class)
public void nonMatch() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage saajMessage = messageFactory.createMessage();
SoapMessage soapMessage = new SaajSoapMessage(saajMessage);
matcher.match(null, soapMessage);
}
@Test(expected = AssertionError.class)
public void nonSoap() throws Exception {
WebServiceMessage message = createMock(WebServiceMessage.class);
matcher.match(null, message);
}
}

View File

@@ -0,0 +1,158 @@
/*
* 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.client2;
import java.io.IOException;
import java.net.URI;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.springframework.ws.mock.client2.WebServiceMock.*;
public class WebServiceMockTest {
private WebServiceTemplate template;
@Before
public void setUp() throws Exception {
template = new WebServiceTemplate();
template.setDefaultUri("http://example.com");
mockWebServiceTemplate(template);
}
@Test
public void mocks() throws Exception {
String uri = "http://example.com";
RequestMatcher requestMatcher1 = EasyMock.createStrictMock("requestMatcher1", RequestMatcher.class);
RequestMatcher requestMatcher2 = EasyMock.createStrictMock("requestMatcher2", RequestMatcher.class);
ResponseCallback responseCallback = EasyMock.createStrictMock(ResponseCallback.class);
requestMatcher1.match(EasyMock.eq(URI.create(uri)), EasyMock.isA(SaajSoapMessage.class));
requestMatcher2.match(EasyMock.eq(URI.create(uri)), EasyMock.isA(SaajSoapMessage.class));
responseCallback.doWithResponse(EasyMock.isA(SaajSoapMessage.class), EasyMock.isA(SaajSoapMessage.class));
EasyMock.replay(requestMatcher1, requestMatcher2, responseCallback);
expect(requestMatcher1).andExpect(requestMatcher2).andRespond(responseCallback);
template.sendSourceAndReceiveToResult(uri, new StringSource("<request xmlns='http://example.com'/>"),
new StringResult());
EasyMock.verify(requestMatcher1, requestMatcher2, responseCallback);
}
@Test
public void payloadMatch() throws Exception {
String request = "<request xmlns='http://example.com'/>";
String response = "<response xmlns='http://example.com'/>";
expect(payload(request)).andRespond(withPayload(response));
StringResult result = new StringResult();
template.sendSourceAndReceiveToResult(new StringSource(request), result);
assertXMLEqual(result.toString(), response);
}
@Test(expected = AssertionError.class)
public void payloadNonMatch() throws Exception {
String expected = "<request xmlns='http://example.com'/>";
expect(payload(expected));
StringResult result = new StringResult();
String actual = "<request xmlns='http://other.com'/>";
template.sendSourceAndReceiveToResult(new StringSource(actual), result);
}
@Test
public void soapHeaderMatch() throws Exception {
final QName soapHeaderName = new QName("http://example.com", "mySoapHeader");
expect(soapHeader(soapHeaderName));
template.sendSourceAndReceiveToResult(new StringSource("<request xmlns='http://example.com'/>"),
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
SoapMessage soapMessage = (SoapMessage) message;
soapMessage.getSoapHeader().addHeaderElement(soapHeaderName);
}
}, new StringResult());
}
@Test(expected = AssertionError.class)
public void soapHeaderNonMatch() throws Exception {
QName soapHeaderName = new QName("http://example.com", "mySoapHeader");
expect(soapHeader(soapHeaderName));
template.sendSourceAndReceiveToResult(new StringSource("<request xmlns='http://example.com'/>"),
new StringResult());
}
@Test
public void connectionMatch() throws Exception {
String uri = "http://example.com";
expect(connectionTo(uri));
template.sendSourceAndReceiveToResult(uri, new StringSource("<request xmlns='http://example.com'/>"),
new StringResult());
}
@Test(expected = AssertionError.class)
public void connectionNonMatch() throws Exception {
String expected = "http://expected.com";
expect(connectionTo(expected));
String actual = "http://actual.com";
template.sendSourceAndReceiveToResult(actual, new StringSource("<request xmlns='http://example.com'/>"),
new StringResult());
}
@Test
public void verifyThreadLocalCleanUp() throws Exception {
String request = "<request xmlns='http://example.com'/>";
String response = "<response xmlns='http://example.com'/>";
expect(payload(request)).andRespond(withPayload(response));
expect(payload(request)).andRespond(withPayload(response));
assertNotNull(MockWebServiceMessageSenderHolder.get());
template.sendSourceAndReceiveToResult(new StringSource(request), new StringResult());
assertNotNull(MockWebServiceMessageSenderHolder.get());
template.sendSourceAndReceiveToResult(new StringSource(request), new StringResult());
assertNull(MockWebServiceMessageSenderHolder.get());
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.client2.integration;
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.client.CustomerCountRequest;
import org.springframework.ws.mock.client.CustomerCountResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.springframework.ws.mock.client2.WebServiceMock.*;
/**
* Integration test for client-side WebService testing. In different package so we can't use the package-protected
* classes.
*
* @author Arjen Poutsma
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("integration-test.xml")
public class IntegrationTest {
@Autowired
private WebServiceTemplate webServiceTemplate;
@Before
public void setUpMocks() throws Exception {
mockWebServiceTemplate(webServiceTemplate);
}
@Test
public void basic() throws Exception {
String expectedRequestPayload = "<customerCountRequest xmlns='http://springframework.org/client'>" +
"<customerName>John Doe</customerName>" + "</customerCountRequest>";
String responsePayload = "<customerCountResponse xmlns='http://springframework.org/client'>" +
"<customerCount>10</customerCount>" + "</customerCountResponse>";
expect(payload(expectedRequestPayload)).andRespond(withPayload(responsePayload));
CustomerCountRequest request = new CustomerCountRequest();
request.setCustomerName("John Doe");
CustomerCountResponse response = (CustomerCountResponse) webServiceTemplate.marshalSendAndReceive(request);
assertEquals(10, response.getCustomerCount());
}
}

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.client.CustomerCountRequest</value>
<value>org.springframework.ws.mock.client.CustomerCountResponse</value>
</list>
</property>
</bean>
</beans>