Feature: Negate a matcher #95

Closed
opened 2025-12-29 08:22:12 +01:00 by adam · 15 comments
Owner

Originally created by @alastairtree on GitHub (Apr 25, 2018).

Originally assigned to: @StefH on GitHub.

Is there any way to negate a matcher, so i could match on the absense of a match. For example what if i want to stub for all requests that do not have an API key header? Or all requests with query param A but missing query param B?

Originally created by @alastairtree on GitHub (Apr 25, 2018). Originally assigned to: @StefH on GitHub. Is there any way to negate a matcher, so i could match on the absense of a match. For example what if i want to stub for all requests that do not have an API key header? Or all requests with query param A but missing query param B?
adam added the featurequestion labels 2025-12-29 08:22:12 +01:00
adam closed this issue 2025-12-29 08:22:12 +01:00
Author
Owner

@StefH commented on GitHub (Apr 26, 2018):

Good question. I thought the RegexMatcher could be solution, but that can only check/not-check on the value from a header, you cannot define a match where the complete api-header is absent...

@StefH commented on GitHub (Apr 26, 2018): Good question. I thought the `RegexMatcher` could be solution, but that can only check/not-check on the value from a header, you cannot define a match where the complete api-header is absent...
Author
Owner

@StefH commented on GitHub (Apr 26, 2018):

Another option could be (in code):

.NotWithHeader("API-Key")

// or

.Not().WithHeader("API-Key")

As mapping, a solution would be:

"Headers": [
	{
		"Name": "API-Key",
		"Matchers": [
			{
			    "Not": true
			}
		]
	}
]

or

"Headers": [
	{
		"Name": "API-Key",
		"Matchers": [
			{
			    "Not": true,
			    "Name": "WildcardMatcher",
			    "Pattern": "application/json*",
			    "IgnoreCase": true
			}
		]
	}
]

or

"Headers": [
	{
		"Name": "API-Key",
		"Matchers": [
			{
			    "Negate": true
			}
		]
	}
]
@StefH commented on GitHub (Apr 26, 2018): Another option could be (in code): ``` c# .NotWithHeader("API-Key") // or .Not().WithHeader("API-Key") ``` As mapping, a solution would be: ``` js "Headers": [ { "Name": "API-Key", "Matchers": [ { "Not": true } ] } ] ``` or ``` js "Headers": [ { "Name": "API-Key", "Matchers": [ { "Not": true, "Name": "WildcardMatcher", "Pattern": "application/json*", "IgnoreCase": true } ] } ] ``` or ``` c# "Headers": [ { "Name": "API-Key", "Matchers": [ { "Negate": true } ] } ] ```
Author
Owner

@alastairtree commented on GitHub (Apr 26, 2018):

It would also be nice if we could apply it elsewhere also - for example on query params. I think I prefer something in the matcher that reverses the match, so that every matcher could be inverted if you wanted. But it could be easily confusing. Perhaps an Enum and a sensible default to make it really explicit?

Request.Create()
     .UsingGet()
     .WithHeader("Accept", "text/html*", MatchBehaviour.AcceptOnMatch) // this would be the default 
     .WithPath("/")


Request.Create()
     .UsingGet()
     .WithHeader("Accept", "text/html*", MatchBehaviour.RejectOnMatch)
     .WithPath("/")

and then in json perhaps:

"Headers": [
	{
		"Name": "API-Key",
		"Matchers": [
			{
			    "RejectOnMatch": true,
			    "Name": "WildcardMatcher",
			    "Pattern": "application/json*",
			    "IgnoreCase": true
			}
		]
	}
]
@alastairtree commented on GitHub (Apr 26, 2018): It would also be nice if we could apply it elsewhere also - for example on query params. I think I prefer something in the matcher that reverses the match, so that every matcher could be inverted if you wanted. But it could be easily confusing. Perhaps an Enum and a sensible default to make it really explicit? ```csharp Request.Create() .UsingGet() .WithHeader("Accept", "text/html*", MatchBehaviour.AcceptOnMatch) // this would be the default .WithPath("/") Request.Create() .UsingGet() .WithHeader("Accept", "text/html*", MatchBehaviour.RejectOnMatch) .WithPath("/") ``` and then in json perhaps: ```json "Headers": [ { "Name": "API-Key", "Matchers": [ { "RejectOnMatch": true, "Name": "WildcardMatcher", "Pattern": "application/json*", "IgnoreCase": true } ] } ] ```
Author
Owner

@StefH commented on GitHub (Apr 27, 2018):

When looking at the original WireMock : http://wiremock.org/docs/request-matching/ (see text It is also possible to perform a negative match)

I think that this would also be an option:

code

// accept matcher (existing code)
Request.Create()
     .UsingGet()
     .WithHeader("API-Key", "123*", true)
     .WithPath("/")

// reject (new)
Request.Create()
     .UsingGet()
     .WithHeader("API-Key", Reject("123*", true))
     .WithPath("/")

or instead of Reject(...), we could use RejectMatch(...) / RejectOnMatch(...) / Not(...) / NoMatch(...) / RejectPattern(...)

json

Your proposal (looks good I think)

"Headers": [
	{
		"Name": "API-Key",
		"Matchers": [
			{
			    "RejectOnMatch": true,
			    "Name": "WildcardMatcher",
			    "Pattern": "123*",
			    "IgnoreCase": true
			}
		]
	}
]

or

option 1 (add a new list : the RejectMatchers)

"Headers": [
	{
		"Name": "API-Key",
		"RejectMatchers": [
			{
			    "Name": "WildcardMatcher",
			    "Pattern": "123*",
			    "IgnoreCase": true
			}
		]
	}
]

or

option 2 (looks like the WireMock.org solution, however the IgnoreCase is a bit strange because it's used in the matching, but now it seems that only the pattern is rejected...)

"Headers": [
	{
		"Name": "API-Key",
		"Matchers": [
			{
			    "Name": "WildcardMatcher",
			    "RejectPattern": "123*",
			    "IgnoreCase": true
			}
		]
	}
]

Maybe some more?

@StefH commented on GitHub (Apr 27, 2018): When looking at the original WireMock : http://wiremock.org/docs/request-matching/ (see text `It is also possible to perform a negative match`) I think that this would also be an option: **code** ``` c# // accept matcher (existing code) Request.Create() .UsingGet() .WithHeader("API-Key", "123*", true) .WithPath("/") // reject (new) Request.Create() .UsingGet() .WithHeader("API-Key", Reject("123*", true)) .WithPath("/") ``` or instead of `Reject(...)`, we could use `RejectMatch(...)` / `RejectOnMatch(...)` / `Not(...)` / `NoMatch(...)` / `RejectPattern(...)` **json** _Your proposal_ (looks good I think) ``` js "Headers": [ { "Name": "API-Key", "Matchers": [ { "RejectOnMatch": true, "Name": "WildcardMatcher", "Pattern": "123*", "IgnoreCase": true } ] } ] ``` or _option 1_ (add a new list : the `RejectMatchers`) ``` js "Headers": [ { "Name": "API-Key", "RejectMatchers": [ { "Name": "WildcardMatcher", "Pattern": "123*", "IgnoreCase": true } ] } ] ``` or _option 2_ (looks like the WireMock.org solution, however the `IgnoreCase` is a bit strange because it's used in the matching, but now it seems that only the pattern is rejected...) ``` js "Headers": [ { "Name": "API-Key", "Matchers": [ { "Name": "WildcardMatcher", "RejectPattern": "123*", "IgnoreCase": true } ] } ] ``` Maybe some more?
Author
Owner

@StefH commented on GitHub (May 1, 2018):

@alastairtree Did you have time to take a look at my last comment?

@StefH commented on GitHub (May 1, 2018): @alastairtree Did you have time to take a look at my last comment?
Author
Owner

@alastairtree commented on GitHub (May 1, 2018):

I don't feel that passionately about the syntax, but having reviewed the various options i think i still prefer my proosal of .WithHeader("Accept", "text/html*", MatchBehaviour.RejectOnMatch) and the "RejectOnMatch": true, json flavour, but happy to be overruled!

@alastairtree commented on GitHub (May 1, 2018): I don't feel that passionately about the syntax, but having reviewed the various options i think i still prefer my proosal of `.WithHeader("Accept", "text/html*", MatchBehaviour.RejectOnMatch)` and the `"RejectOnMatch": true,` json flavour, but happy to be overruled!
Author
Owner

@StefH commented on GitHub (May 1, 2018):

I'll keep your proposal and I will update the code. Probably I'll send a PR review to you when it's ready.

@StefH commented on GitHub (May 1, 2018): I'll keep your proposal and I will update the code. Probably I'll send a PR review to you when it's ready.
Author
Owner

@alastairtree commented on GitHub (May 1, 2018):

Thats very kind! It is a good feature I think, but I am not urgently in need at the moment as I found a work around using priorities, so by all means put other issues ahead of this one. Very happy to code review anything though.

@alastairtree commented on GitHub (May 1, 2018): Thats very kind! It is a good feature I think, but I am not urgently in need at the moment as I found a work around using priorities, so by all means put other issues ahead of this one. Very happy to code review anything though.
Author
Owner

@alastairtree commented on GitHub (May 4, 2018):

Had a look at that branch and its looking good.

@alastairtree commented on GitHub (May 4, 2018): Had a look at that branch and its looking good.
Author
Owner

@StefH commented on GitHub (May 4, 2018):

I'm not done yet. Have to write more unit tests and do some real testing.

@StefH commented on GitHub (May 4, 2018): I'm not done yet. Have to write more unit tests and do some real testing.
Author
Owner

@StefH commented on GitHub (May 6, 2018):

Hello @alastairtree.

Now I think I've updated and tested all the code, can you now please do a review and if possible also run some real tests to see if the behaviour is correct?

@StefH commented on GitHub (May 6, 2018): Hello @alastairtree. Now I think I've updated and tested all the code, can you now please do a review and if possible also run some real tests to see if the behaviour is correct?
Author
Owner

@StefH commented on GitHub (May 11, 2018):

@alastairtree, can you do a code-review please?

@StefH commented on GitHub (May 11, 2018): @alastairtree, can you do a code-review please?
Author
Owner

@alastairtree commented on GitHub (May 12, 2018):

Looking good @StefH - added some little bits in #134

@alastairtree commented on GitHub (May 12, 2018): Looking good @StefH - added some little bits in #134
Author
Owner

@alastairtree commented on GitHub (May 16, 2018):

All looking good @StefH. I have added a bit of docs to https://github.com/WireMock-Net/WireMock.Net/wiki/Stubbing-and-Request-Matching#reversing-the-match-behaviour-with-matchbehaviourrejectonmatch

@alastairtree commented on GitHub (May 16, 2018): All looking good @StefH. I have added a bit of docs to https://github.com/WireMock-Net/WireMock.Net/wiki/Stubbing-and-Request-Matching#reversing-the-match-behaviour-with-matchbehaviourrejectonmatch
Author
Owner

@StefH commented on GitHub (May 16, 2018):

Very cool !!! Thank you very much.

@StefH commented on GitHub (May 16, 2018): Very cool !!! Thank you very much.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net#95