Mockito verify fails, shows additional empty line
When running JUnit tests on a legacy code base at work I got the familiar “Argument(s) are different! [….] Actual invocation has different arguments” notice from Mockito. I ran the tests from the command line, but as I could see no difference between the expected and actual output I re-ran the tests inside IntelliJ to investigate further, resulting in this:

Notice the trailing newline in the actual request made.
From the reported error above it wasn’t straight forward figuring out the underlying issue, so I though I’d share this quick write-up just in case others stumble on the same issue.
Extract from the test code:
String expectedSoapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn1=\"urn:com.acme.system:S-1-0\" xmlns:urn=\"urn:com.acme.system:S-1-0\">\n" +
" <soapenv:Body>\n" +
" <urn1:SMSRequest>\n" +
" <urn:id>1234567890</urn:id>\n" +
" <urn:timestamp>1623137600000</urn:timestamp>\n" +
" <urn:destination>1234</urn:destination>\n" +
" <urn:originator>99999999</urn:originator>\n" +
" <urn:service>TEST</urn:service>\n" +
" <urn:message>message</urn:message>\n" +
" </urn1:SMSRequest>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
HttpHeaders headers = new HttpHeaders();
headers.set(AUTHORIZATION, "Basic " + encodeBasicAuth(config.getUsername(), config.getPassword(), UTF_8));
HttpEntity<String> expectedHttpEntity = new HttpEntity<>(expectedSoapRequest, headers);
verify(restTemplateMock).exchange(eq(url), eq(POST), eq(expectedHttpEntity), eq(String.class));
This test ran fine on my coworker’s linux systems, but on my Windows laptop it failed with the above newline issue. After debugging the issue I found that the issue was related to the use of “\n” in the test code.
Extract from the production code:
private String buildSoapRequest(Message message) {
String xmlTemplate =
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn1=\"urn:com:acme:system:S-1-0\" xmlns:urn=\"urn:com.acme.system:S-1-0\">%n" +
" <soapenv:Body>%n" +
" <urn1:SMSRequest>%n" +
" <urn:id>%s</urn:id>%n" +
" <urn:timestamp>%d</urn:timestamp>%n" +
" <urn:destination>%s</urn:destination>%n" +
" <urn:originator>%s</urn:originator>%n" +
" <urn:service>%s</urn:service>%n" +
" <urn:message>%s</urn:message>%n" +
" </urn1:SMSRequest>%n" +
" </soapenv:Body>%n" +
"</soapenv:Envelope>";
return String.format(
xmlTemplate,
message.getId(),
message.getTimestamp(),
message.getDestination(),
message.getOriginator(),
message.getService(),
StringEscapeUtils.escapeXml11(message.getMessage()));
}
Notice the production code’s use of “%n” versus the test code’s use of “\n”. On linux systems both yields the same result, but on Windows systems they don’t. The fix was easy:
<!-- wp:code {"lineNumbers":false} -->
<pre class="wp-block-code"><code lang="java" class="language-java">String expectedSoapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn1=\"urn:com.acme.system:S-1-0\" xmlns:urn=\"urn:com.acme.system:S-1-0\">%n" +
" <soapenv:Body>%n" +
" <urn1:SMSRequest>%n" +
" <urn:id>1234567890</urn:id>%n" +
" <urn:timestamp>1623137600000</urn:timestamp>%n" +
" <urn:destination>1234</urn:destination>%n" +
" <urn:originator>99999999</urn:originator>%n" +
" <urn:service>TEST</urn:service>%n" +
" <urn:message>message</urn:message>%n" +
" </urn1:SMSRequest>%n" +
" </soapenv:Body>%n" +
"</soapenv:Envelope>";
String expectedFormattedRequest = String.format(expectedSoapRequest);
HttpHeaders headers = new HttpHeaders();
headers.set(AUTHORIZATION, "Basic " + encodeBasicAuth(config.getUsername(), config.getPassword(), UTF_8));
HttpEntity<String> expectedHttpEntity = new HttpEntity<>(expectedFormattedRequest, headers);
verify(restTemplateMock).exchange(eq(url), eq(POST), eq(expectedHttpEntity), eq(String.class));</code></pre>
<!-- /wp:code -->