pact-foundation/pact-net

Are header names modified by the mock service?

wscalf opened this issue · 11 comments

I'm attempting to mock a vendor's service for unit test purposes, and it requires an access_token header (specifically "access_token") and would like to assert that the request at least contains a header with that name. Problem is, when I include something like this in my ProviderServiceRequest object:

                    Headers = new Dictionary<string, Object>()
                    {
                        ["Content-Type"] = "application/json; charset=utf-8",
                        ["access_token"] = Match.Type(Token.WriteToken())
                    }

..I get something like the following in my pact log:

Description of differences
--------------------------------------
* Could not find key "access_token" (keys present are: Content-Length, Content-Type, Accept, Access-Token, Host, Expect, Version) at $.headers

Notice that Access-Token is an options, but access_token is not. I've verified both that, when I debug an application processing this request, the header name is reflected as access_token in the current HttpContext, and that the code under test works with the vendor's service (whereas manually sending Access-Token does not.)

Is Pact changing the header names it receives prior to checking for valid interactions?

Yes, it is. It's actually Rack, the http library that does the http calls in the test cases. It assumes that all headers are in the standard format (underscores really aren't standard, I have to say). Nonetheless, there is a workaround for this scenario. I'll ferret it out and get back to you.

@neilcampbell @wscalf what this is going to require is adding a --monkeypatch FILE option to the mock service AND the verifier calls. The FILE is the absolute path to a ruby "monkeypatch" file that I will give you @wscalf. Two of them in fact - one for the mock service and one for the verifier. It will change the code of just your instance of the mock service and verifier.

@wscalf, Neil is moving house at the moment and doesn't have a lot of time for coding - is this a PR you reckon you could pick up? (I'm afraid I don't know the first thing about .net development, so I can't help out with this part) All you'd need to do is find the part of the code that exposes the mock service and verification properties, and allow a monkeypatch file path to be set. That needs to be passed down to the command line arguments that call pact-mock-service and pact-provider-verifier.

@bethesque Sounds nice and hacky 😄
Are you able to post a gist (or something) to the file here, just in case someone finds the issue and has the same problem?
I should be able to find some time to get this working, it should be pretty straight forward. I'll update to the latest standalone core in the process.

Ok, I've gotten a work around, but I've just realised it's for the wrong side. I fixed the verification part.

I'll have a look at the consumer side when I get a chance.

I'm attempting to mock a vendor's service for unit test purposes

But really, please read the "what is pact not good for?" section on this page https://docs.pact.io/documentation/what_is_pact_good_for.html. Pact is probably not the best tool for your situation.

If you do really want to use pact, you'll need the consumer_monkey_patch.rb file in this commit pact-foundation/pact-ruby-standalone-e2e-example@4ede21c

Ok, @neilcampbell can you update to standalone 1.43.1 when you have a chance? @wscalf I have written some monkeypatching code that I'm not proud of, but it will allow the underscored headers to be preserved. I've saved you from having to dirty yourself with the horrible code that had to be written to reverse what is very much a baked in contention in Rack/Ruby!

I have updated PactNet (2.3.0) to pass through this option. All you need to do is set MonkeyPatchFile on both the PactConfig (for the mock provider service) and PactVerifierConfig (for the verifier). As Beth mentioned it needs to be an absolute path to the monkey patch ruby file.

I've fixed it properly. No monkeypatching is required. But it's good to have the option in there.

You've got the latest standalone, yeah?

@bethesque Oh cool! Yep updated to 1.43.1