diff --git a/test/src/main/java/org/springframework/ws/mock/client/SchemaValidatingRequestMatcher.java b/test/src/main/java/org/springframework/ws/mock/client/SchemaValidatingRequestMatcher.java
new file mode 100644
index 00000000..795e6f31
--- /dev/null
+++ b/test/src/main/java/org/springframework/ws/mock/client/SchemaValidatingRequestMatcher.java
@@ -0,0 +1,51 @@
+/*
+ * 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.client;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+
+import org.springframework.util.Assert;
+import org.springframework.util.ObjectUtils;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.xml.validation.XmlValidator;
+
+import org.xml.sax.SAXParseException;
+
+/**
+ * Uses the {@link XmlValidator} to validate request payload.
+ *
+ * @author Lukas Krecan
+ * @since 2.0
+ */
+class SchemaValidatingRequestMatcher implements RequestMatcher {
+
+ private final XmlValidator xmlValidator;
+
+ public SchemaValidatingRequestMatcher(XmlValidator xmlValidator) {
+ Assert.notNull(xmlValidator, "XmlValidator has to be set");
+ this.xmlValidator = xmlValidator;
+ }
+
+ public void match(URI uri, WebServiceMessage request) throws IOException, AssertionError {
+ SAXParseException[] exceptions = xmlValidator.validate(request.getPayloadSource());
+ if (!ObjectUtils.isEmpty(exceptions)) {
+ throw new AssertionError("XML is not valid: " + Arrays.toString(exceptions));
+ }
+ }
+}
diff --git a/test/src/main/java/org/springframework/ws/mock/client/WebServiceMock.java b/test/src/main/java/org/springframework/ws/mock/client/WebServiceMock.java
index 9735265d..1cd95fb4 100644
--- a/test/src/main/java/org/springframework/ws/mock/client/WebServiceMock.java
+++ b/test/src/main/java/org/springframework/ws/mock/client/WebServiceMock.java
@@ -26,6 +26,8 @@ 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.validation.XmlValidator;
+import org.springframework.xml.validation.XmlValidatorFactory;
/**
* @author Arjen Poutsma
@@ -84,6 +86,27 @@ public abstract class WebServiceMock {
return new PayloadDiffMatcher(createResourceSource(payload));
}
+ /**
+ * Expects the payload to validate against the given XSD schema(s).
+ *
+ * @param schema the schema
+ * @param furtherSchemas further schemas, if necessary
+ * @return the request matcher
+ */
+ public static RequestMatcher validPayload(Resource schema, Resource... furtherSchemas) {
+ try {
+ Resource[] joinedSchemas = new Resource[furtherSchemas.length + 1];
+ joinedSchemas[0] = schema;
+ System.arraycopy(furtherSchemas, 0, joinedSchemas, 1, furtherSchemas.length);
+ XmlValidator validator =
+ XmlValidatorFactory.createValidator(joinedSchemas, XmlValidatorFactory.SCHEMA_W3C_XML);
+ return new SchemaValidatingRequestMatcher(validator);
+ }
+ catch (IOException ex) {
+ throw new IllegalArgumentException("Schema(s) could not be opened", ex);
+ }
+ }
+
/**
* Expects the given SOAP header in the outgoing message.
*
diff --git a/test/src/test/java/org/springframework/ws/mock/client/SchemaValidatingRequestMatcherTest.java b/test/src/test/java/org/springframework/ws/mock/client/SchemaValidatingRequestMatcherTest.java
new file mode 100644
index 00000000..5d9eea33
--- /dev/null
+++ b/test/src/test/java/org/springframework/ws/mock/client/SchemaValidatingRequestMatcherTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.client;
+
+import java.io.IOException;
+
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.xml.transform.StringSource;
+import org.springframework.xml.validation.XmlValidator;
+import org.springframework.xml.validation.XmlValidatorFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.*;
+
+public class SchemaValidatingRequestMatcherTest {
+
+ private Resource schema2;
+
+ private Resource schema1;
+
+ private WebServiceMessage message;
+
+ @Before
+ public void setUp() {
+ message = createMock(WebServiceMessage.class);
+ schema1 = new ClassPathResource("schemaValidatingRequestMatcherTest.xsd", SchemaValidatingRequestMatcherTest.class);
+ schema2 = new ByteArrayResource("".getBytes());
+ }
+
+ @Test
+ public void singleSchemaMatch() throws IOException, AssertionError {
+ expect(message.getPayloadSource()).andReturn(new StringSource(
+ "0text"));
+
+ RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1);
+
+ replay(message);
+
+ requestMatcher.match(null, message);
+
+ verify(message);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void singleSchemaNonMatch() throws IOException, AssertionError {
+ expect(message.getPayloadSource()).andReturn(new StringSource(
+ "atext"));
+
+ RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1);
+
+ replay(message);
+
+ requestMatcher.match(null, message);
+
+ verify(message);
+ }
+
+ @Test
+ public void multipleSchemaMatch() throws IOException, AssertionError {
+ expect(message.getPayloadSource()).andReturn(new StringSource(
+ "0text"));
+
+ RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1, schema2);
+
+ replay(message);
+
+ requestMatcher.match(null, message);
+
+ verify(message);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void multipleSchemaNotOk() throws IOException, AssertionError {
+ expect(message.getPayloadSource()).andReturn(new StringSource(
+ "atext"));
+
+ RequestMatcher requestMatcher = WebServiceMock.validPayload(schema1, schema2);
+
+ replay(message);
+
+ requestMatcher.match(null, message);
+
+ verify(message);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void multipleSchemaDifferentOrderNotOk() throws IOException, AssertionError {
+ expect(message.getPayloadSource()).andReturn(new StringSource(
+ "atext"));
+
+ RequestMatcher requestMatcher = WebServiceMock.validPayload(schema2, schema1);
+
+ replay(message);
+
+ requestMatcher.match(null, message);
+
+ verify(message);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void xmlValidatorNotOk() throws IOException, AssertionError {
+ expect(message.getPayloadSource()).andReturn(new StringSource(
+ "atext"));
+
+ XmlValidator validator = XmlValidatorFactory.createValidator(schema1, XmlValidatorFactory.SCHEMA_W3C_XML);
+ RequestMatcher requestMatcher = new SchemaValidatingRequestMatcher(validator);
+
+ replay(message);
+
+ requestMatcher.match(null, message);
+
+ verify(message);
+ }
+}
diff --git a/test/src/test/java/org/springframework/ws/mock/client/WebServiceMockTest.java b/test/src/test/java/org/springframework/ws/mock/client/WebServiceMockTest.java
index bd29dc9c..33544d9d 100644
--- a/test/src/test/java/org/springframework/ws/mock/client/WebServiceMockTest.java
+++ b/test/src/test/java/org/springframework/ws/mock/client/WebServiceMockTest.java
@@ -22,6 +22,8 @@ import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.core.io.Resource;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
@@ -154,7 +156,7 @@ public class WebServiceMockTest {
template.sendSourceAndReceiveToResult(request, new StringResult());
assertNull(MockWebServiceMessageSenderHolder.get());
}
-
+
@Test(expected = AssertionError.class)
public void unexpectedConnection() throws Exception {
Source request = new StringSource("");
@@ -166,5 +168,28 @@ public class WebServiceMockTest {
template.sendSourceAndReceiveToResult(request, new StringResult());
}
+ @Test
+ public void xsdMatch() throws Exception {
+ Resource schema = new ByteArrayResource(
+ "".getBytes());
+
+ expect(validPayload(schema));
+
+ StringResult result = new StringResult();
+ String actual = "";
+ template.sendSourceAndReceiveToResult(new StringSource(actual), result);
+ }
+
+ @Test(expected = AssertionError.class)
+ public void xsdNonMatch() throws Exception {
+ Resource schema = new ByteArrayResource(
+ "".getBytes());
+
+ expect(validPayload(schema));
+
+ StringResult result = new StringResult();
+ String actual = "";
+ template.sendSourceAndReceiveToResult(new StringSource(actual), result);
+ }
}
diff --git a/test/src/test/resources/org/springframework/ws/mock/client/schemaValidatingRequestMatcherTest.xsd b/test/src/test/resources/org/springframework/ws/mock/client/schemaValidatingRequestMatcherTest.xsd
new file mode 100644
index 00000000..a0bc71eb
--- /dev/null
+++ b/test/src/test/resources/org/springframework/ws/mock/client/schemaValidatingRequestMatcherTest.xsd
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+