First and foremost thank you very much for creating WireMock and making it available for everyone!
It seems I found a bug though: URL encoded parameters never match. The attached tests use WireMock to access the same URL:
This is on Android and a build.gradle file is attached too. Please not that unlike noted at http://handstandsam.com/2016/01/30/running-wiremock-on-android/ you need to specify "exclude group: 'org.ow2.asm', module: 'asm'" and not "exclude group: 'asm', module: 'asm'" to get rid of the Duplicate Class Exception regarding the org/objectweb/asm/AnnotationVisitor.class.
The decision to match on unencoded values was deliberate. This makes query parameter matching consistent with other types of request parameters.
Is there a specific reason you need to encode the params before verifying?
Of course I want of test the actual code and not add a test path. That's the benefit of using natural system borders for testing.
As others requested even more lenience in URL handling the matching of URLs and parameters has to be changed anyway I guess.
When did the behavior change? I'm sure I was able to match for %40 in the past.
In my eyes, it is absolutely necessary for all matching to happen against what was transmitted on the _wire_. That's the only way I can guarantee that my application does what it is supposed to do. Why else would it be called _wire_ mock? URL decoding should not happen anywhere.
In many cases it is vital that a value is properly URL encoded, otherwise it might break the URL. Sending requests without URL encoding by accident (by using + for concatenation) is trivial. I would like to guard against this with a unit test. Am I understanding correctly that this is not currently possible with wiremock 2.1.12+ (maybe earlier)?
Also, error messages of the form
expected:<GET /td/rest/addresses?email=zuckel%40gmail.com>
but was :<GET /td/rest/addresses?email=zuckel%40gmail.com>
are less than helpful. This is already a good indicator that there's something fishy about the current approach.
The same goes for near misses:
"nearMisses" : [ {"
"request" : {"
"url" : "/td/rest/addresses?email=zuckel%40gmail.com","
"absoluteUrl" : "http://localhost:44745/td/rest/addresses?email=zuckel%40gmail.com","
"method" : "GET","
...},"
"requestPattern" : {"
"urlPath" : "/td/rest/addresses","
"method" : "GET","
"queryParameters" : {"
"email" : {"
"equalTo" : "zuckel%40gmail.com""
...}}}
} ]"
I've been debugging for quite some time until I found out that this is an actual issue with wiremock and not my fault or some weird dependency incompatibility.
How can we resolve this? I was about to create a pull request for raw query param matching, but you said the current behavior is deliberate.
Adding an example where I really need the encoding to be correct. This is from daily use:
@Test
public void urlEncodingWorks() throws Exception {
// # -> 23, % -> 25, @ -> 40
stubFor(get(urlEqualTo(EMAIL_PATH + "?email=hash%23percent%2540word%40gmail.com")).willReturn(aResponse().withStatus(200)));
gateway.findEmail(new EmailAddress("hash#percent%[email protected]"));
}
Apologies, I think I've mislead you earlier in this thread. URLs are still matched encoded. It's query parameters (specified separately) that are decoded.
If you're seeing cases where an encoded URL isn't matching despite being the same, please could you provide a full test case?
For an example of the URL path not matching, see #527.
As for query parameters, that means if I want to verify they are encoded correctly the only way to do so is using the URL matchers (urlEqualTo(), ...) ? Is there a way to write my own custom matcher for that?
I got this issue when I have brackets in params:
com.github.tomakehurst.wiremock.client.VerificationException: No requests exactly matched. Most similar request was: expected:<
GET
/accept/accId?signed_at=2019-01-01T01:00:00Z%255BUTC%255D
Query: signed_at = 2019-01-01T01:00:00Z[UTC]
> but was:<
GET
/accept/accId?signed_at=2019-01-01T01:00:00Z%255BUTC%255D
signed_at: 2019-01-01T01:00:00Z%5BUTC%5D
>
Most helpful comment
I got this issue when I have brackets in params: