Evening, I'm not sure which channel to ask this qu...
# general
b
Evening, I'm not sure which channel to ask this question so I'll start here and post elsewhere after some guidance. I have a scenario where there are two consumers of the same endpoint (lets call it person/${personId}/phoneNumbers which takes filter parameters A, B, C, D and E Consumer A - Sends a requests with request parameters A,B and C as those are the only filter parameters it is concerned about. Consumer B - Sends a requests with request parameters A,D and E as those are the only filter parameters it is concerned about. There is a state handler setup that handles both requests (I didn't think it was wise for the provider to have multiple handers for the same endpoint) Consumer A is already implemented using state parameters to set values for the request parameters A, B and C. These values are setup in the statehandlers mocks to match the request correctly and return the result. The issue is that Consumer B is not setting values for state parameters B and C, but is setting values for D and E, so the mocked repo is not set correctly. I feel that the solution is to • Avoid setting stateparameter for optional request parameters. Have each consumer set their own parameters ◦ For example, if a consumer can send one of two values, it could send two status, then
.matchQuery("status", "(DRAFT|ACTIVE)", "ACTIVE")
◦ The test will check that the value is ACTIVE, but the contract will permit either DRAFT or ACTIVE as the consumer could use either value. • Relax the stubbed repository query to accept all parameters. Therefore instead of setting up the repo mocks with the state parameters we send, we accept org.mockito.any() in order to return a result This way we are still following Postel's Law, "strict" with what we send out but flexible with what is returned. Is this the correct way to approach the issue of two consumers and one provider state handler?
I feel like I'm trying to assert optional request parameters So, Consumer A - Sends a requests with request parameters A,B and C
test?paramA=1&paramB=2&paramC=3
And Consumer B - Sends a requests with request parameters A,D and E
test?paramA=1&paramD=2&paramE=3
Consumer A will want a state parameter for B and C and nothing for D and E Consumer B will want a state parameter for D and E and nothing for B and C If I updated the state change handler to cover all possible state parameters across all consumers then the request parameters from state parameters then both consumers will send A, B, C, D and E. My issue, really consumer A is sending values for D and E that it doesn't actually use. Same with consumer B sending B and C. If the provider made a change (made parameter C mandatory) then we know that this will break the contract that consumer B has, thus we know the impact.
m
.matchQuery(“status”, “(DRAFT|ACTIVE)“, “ACTIVE”)
this has no effect on the provider verification - it’s a request side matcher. The problem you have is that the provider test doesn’t know how to support both use cases. Personally, I’d opt for two separate `state`s on the tests, and setup the state for each scenario differently.
i.e.
There is a state handler setup that handles both requests (I didn’t think it was wise for the provider to have multiple handers for the same endpoint)
I think this should be two separate state handlers
b
Thanks very much for taking the time to respond @Matt (pactflow.io / pact-js / pact-go) We are considering the provider sending all state parameters for all the possible request parameters. The consumer (client) will send the parameters it is interested in. The mocked repo then has to support received subsets of the state parameters. This way we can keep to on state handler that handles both consumers. (Of course if another consumer comes aboard that sends another different subset of parameters, then an update will be required to the state handler to support it.
m
No worries!
We are considering the provider sending all state parameters for all the possible request parameters.
For clarity. Do you mean, supporting multiple state params for the different scenarios?
b
So, we have an API that can take optional values A, B, C, D and E. We have one consumer that sends A, B, C and another that sends A, D and E. Therefore, the change state handler will return a map of A, B, C, D and E. The thinking is that Consumer A will use A, B and C
Copy code
.queryParameterFromProviderState("paramA", "${useParamAFromStateHandler}", "exampleOfParameterAforTest")
.queryParameterFromProviderState("paramB", "${useParamBFromStateHandler}", "exampleOfParameterBforTest")
.queryParameterFromProviderState("paramC", "${useParamCFromStateHandler}", "exampleOfParameterCforTest")
Consumer B will use A, D and E.
Copy code
.queryParameterFromProviderState("paramA", "${useParamAFromStateHandler}", "exampleOfParameterAforTest")
.queryParameterFromProviderState("paramD", "${useParamDFromStateHandler}", "exampleOfParameterDforTest")
.queryParameterFromProviderState("paramE", "${useParamEFromStateHandler}", "exampleOfParameterEforTest")
The the mocked repo will have to check the values of the parameters it receives So, to handle a request from Consumer A, if A, B, C have a value and D and E are null, then return expected body and for Consumer B, if A, D, E have a value and B and C are null, then return expected body.
👍 1
.matchQuery(“status”, “(DRAFT|ACTIVE)“, “ACTIVE”)
this has no effect on the provider verification - it’s a request side matcher. The problem you have is that the provider test doesn’t know how to support both use cases.
Just to confirm, this is the consumer (client) side and it will send a status of either DRAFT or ACTIVE.
1
m
ah I see, you’re using that feature. That makes sense
b
Yeah, sorry, I don't often post questions, so missed any key clarifications. Thanks again for taking time to respond.
m
You're most welcome!