From 5e73b4c5549cec75a70b2f36c0647e1e82777df8 Mon Sep 17 00:00:00 2001
From: Felix Prasse <1330854+flx5@users.noreply.github.com>
Date: Thu, 30 May 2024 11:23:05 +0200
Subject: [PATCH] Allow usage of XMLUnit placeholders in request and response
matchers. (#1417)
Signed-off-by: @corneil
---
spring-ws-test/pom.xml | 6 +++++
.../matcher/xmlunit2/PayloadDiffMatcher.java | 4 +++
.../xmlunit2/SoapEnvelopeDiffMatcher.java | 9 ++++++-
.../xmlunit2/PayloadDiffMatcherTest.java | 15 +++++++++++
.../xmlunit2/SoapEnvelopeDiffMatcherTest.java | 25 +++++++++++++++++++
src/main/asciidoctor/client.adoc | 5 +++-
src/main/asciidoctor/server.adoc | 5 +++-
7 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/spring-ws-test/pom.xml b/spring-ws-test/pom.xml
index 04ea34123..fcd59c699 100644
--- a/spring-ws-test/pom.xml
+++ b/spring-ws-test/pom.xml
@@ -51,6 +51,12 @@
+
+ org.xmlunit
+ xmlunit-placeholders
+ ${xmlunit.version}
+
+
org.springframework
spring-test
diff --git a/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcher.java b/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcher.java
index cb5e3be2f..7e4cf68d9 100644
--- a/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcher.java
+++ b/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcher.java
@@ -28,6 +28,8 @@
import org.w3c.dom.Document;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.diff.Diff;
+import org.xmlunit.diff.DifferenceEvaluators;
+import org.xmlunit.placeholder.PlaceholderDifferenceEvaluator;
/**
* Matches {@link Source} payloads.
@@ -68,6 +70,8 @@ protected Diff createDiff(Source payload) {
return DiffBuilder.compare(expectedDocument) //
.withTest(actualDocument) //
.ignoreWhitespace() //
+ .withDifferenceEvaluator(
+ DifferenceEvaluators.chain(new PlaceholderDifferenceEvaluator(), DifferenceEvaluators.Default))
.checkForSimilar() //
.build();
}
diff --git a/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcher.java b/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcher.java
index 9263193f6..ed613773d 100644
--- a/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcher.java
+++ b/spring-ws-test/src/main/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcher.java
@@ -32,6 +32,8 @@
import org.w3c.dom.Document;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.diff.Diff;
+import org.xmlunit.diff.DifferenceEvaluators;
+import org.xmlunit.placeholder.PlaceholderDifferenceEvaluator;
/**
* Matches {@link Source} SOAP envelopes.
@@ -56,7 +58,12 @@ protected void match(SoapMessage soapMessage) throws IOException, AssertionError
Document actualDocument = soapMessage.getDocument();
Document expectedDocument = createDocumentFromSource(expected);
- Diff diff = DiffBuilder.compare(expectedDocument).ignoreWhitespace().withTest(actualDocument).checkForSimilar()
+ Diff diff = DiffBuilder.compare(expectedDocument)
+ .ignoreWhitespace()
+ .withTest(actualDocument)
+ .withDifferenceEvaluator(
+ DifferenceEvaluators.chain(new PlaceholderDifferenceEvaluator(), DifferenceEvaluators.Default))
+ .checkForSimilar()
.build();
assertTrue("Envelopes are different, " + diff.toString(), !diff.hasDifferences());
}
diff --git a/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcherTest.java b/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcherTest.java
index 208200a08..c922b2f64 100644
--- a/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcherTest.java
+++ b/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/PayloadDiffMatcherTest.java
@@ -43,6 +43,21 @@ public void match() {
verify(message);
}
+ @Test
+ public void matchWithXmlIgnore() {
+
+ var xml = "%s";
+ WebServiceMessage message = createMock(WebServiceMessage.class);
+
+ expect(message.getPayloadSource()).andReturn(new StringSource(xml.formatted("1234"))).times(2);
+ replay(message);
+
+ var matcher = new PayloadDiffMatcher(new StringSource(xml.formatted("${xmlunit.ignore}")));
+ matcher.match(message);
+
+ verify(message);
+ }
+
@Test
public void matchIgnoringWhitespace() {
diff --git a/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcherTest.java b/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcherTest.java
index bb5eaa6ed..d473882d6 100644
--- a/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcherTest.java
+++ b/spring-ws-test/src/test/java/org/springframework/ws/test/support/matcher/xmlunit2/SoapEnvelopeDiffMatcherTest.java
@@ -22,6 +22,7 @@
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
+import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import org.junit.jupiter.api.Test;
@@ -30,6 +31,8 @@
import org.springframework.xml.transform.TransformerHelper;
import org.w3c.dom.Document;
+import java.io.IOException;
+
public class SoapEnvelopeDiffMatcherTest {
@Test
@@ -76,4 +79,26 @@ public void nonMatch() {
matcher.match(message);
});
}
+
+ @Test
+ public void matchWithXmlIgnore() throws TransformerException, IOException {
+ String xml = """
+
+
+
+ %s
+ """;
+
+ String actual = String.format(xml, "1");
+ DOMResult result = new DOMResult();
+ TransformerHelper transformerHelper = new TransformerHelper();
+ transformerHelper.transform(new StringSource(actual), result);
+ SoapMessage message = createMock(SoapMessage.class);
+ expect(message.getDocument()).andReturn((Document) result.getNode()).once();
+ replay(message);
+
+ String expected = String.format(xml, "${xmlunit.ignore}");
+ SoapEnvelopeDiffMatcher matcher = new SoapEnvelopeDiffMatcher(new StringSource(expected));
+ matcher.match(message);
+ }
}
diff --git a/src/main/asciidoctor/client.adoc b/src/main/asciidoctor/client.adoc
index 32795e195..b4babdddb 100644
--- a/src/main/asciidoctor/client.adoc
+++ b/src/main/asciidoctor/client.adoc
@@ -457,7 +457,7 @@ The `RequestMatchers` class provides the following request matchers:
| Expects any sort of request.
| `payload()`
-| Expects a given request payload.
+| Expects a given request payload. May include https://github.com/xmlunit/user-guide/wiki/Placeholders[XMLUnit Placeholders]
| `validPayload()`
| Expects the request payload to validate against given XSD schemas.
@@ -468,6 +468,9 @@ The `RequestMatchers` class provides the following request matchers:
| `soapHeader()`
| Expects a given SOAP header to exist in the request message.
+| `soapEnvelope()`
+| Expects a given SOAP payload. May include https://github.com/xmlunit/user-guide/wiki/Placeholders[XMLUnit Placeholders]
+
| `connectionTo()`
| Expects a connection to the given URL.
|===
diff --git a/src/main/asciidoctor/server.adoc b/src/main/asciidoctor/server.adoc
index aacf13899..f0e854f2a 100644
--- a/src/main/asciidoctor/server.adoc
+++ b/src/main/asciidoctor/server.adoc
@@ -1244,7 +1244,7 @@ The `ResponseMatchers` class provides the following response matchers:
| Description
| `payload()`
-| Expects a given response payload.
+| Expects a given response payload. May include https://github.com/xmlunit/user-guide/wiki/Placeholders[XMLUnit Placeholders].
| `validPayload()`
| Expects the response payload to validate against given XSD schemas.
@@ -1255,6 +1255,9 @@ The `ResponseMatchers` class provides the following response matchers:
| `soapHeader()`
| Expects a given SOAP header to exist in the response message.
+| `soapEnvelope()`
+| Expects a given SOAP payload. May include https://github.com/xmlunit/user-guide/wiki/Placeholders[XMLUnit Placeholders].
+
| `noFault()`
| Expects that the response message does not contain a SOAP Fault.