hi there, is there a way to define PactDslWithProv...
# pact-jvm
p
hi there, is there a way to define PactDslWithProvided builder with optional arrays ? { "data": { "titles": [ { "titleId": "1234", "parenttitleId": "5678", "titleName": "test", "titleOwner": "xyzb", "titleArchitect": "abcde", "titleLeads": [ //optional array -- how to mention this - if exist - example to be of this type , if not - ignore the verification { "lead1": "xyz", "isEndorsed": true }, { "lead2": "abcd", "isEndorsed": false } ] }, { "titleId": "12345", "parenttitleId": "5678", "titleName": "test", "titleOwner": "xyzba", "titleArchitect": "abcdef" } ] } }
u
Use the
eachLike
function
m
for “optional”, please also see the below link to properly cover your use case 👇 (howtooptional)
👍 1
p
this still fails at provider end if the optional array 'titleLeads' not returned:
Copy code
.body(new PactDslJsonBody().object("data")
                                .minArrayLike("titles", 1)
                                .stringType("titleId", "abcd01")
                                .stringType("parentTitleId", "abcd01")
                                .stringType("titleName", "ABCD")
                                .stringType("titleOwner", "abcd01")
                                .eachLike("titleLeads")
                                .stringType("employeeId")
                                .booleanType("isEndorsed")
                                .closeObject()
                        .closeArray()
                .closeObject()
        .closeArray())
.toPact();
u
Oh, you mean it is not present at all. No, it won't support that. Refer to the link posted above.
p
Based on the FAQ, looks like there is no option to set the optional ..
u
We don't support optional values.
p
got it ! and the reasoning behind that .. however if we check for say retrieve all end point where in the first item might have or might not have the optional array and hence in this case - looks like there is no way to verify it
u
You need to create two tests, one with the value and one without. Then define a different provider state for each case.
p
yeah got that.. but definitely all microservice will have retrieveall list endpoint where in this specific need arises ! and looks like as of now there is no way to verify in pact ..
I hope its a valid scenario .. do you guys reckon there would be any future support for this ?
u
Pact won't support optional fields, you need to use tests for the different cases
t
A key point here is that you’re not describing the response schema in your pact test. You are defining a complete example. Pact is contract-by-example, not contract-by-schema. A matcher doesn’t say “this might be in the response”, it says “this test covers all responses that pass this matcher”.
So, yes, this is a valid scenario. And the way you cover it in Pact is with two different tests.
m
I wonder if in this scenario (and possibly many others) we should start using the word “test” or “unit test”, instead of “Pact test” i.e. how do you write a unit test that A is either an X or a Y? You write two tests. You don’t write a single unit test that has one variant and if it passes call it done. You write a second one for the other variant to cover both branches
Pact is no different
t
I like it.
p
thanks for the details.. I completely understand what you mean and pact test is exactly similar to unit test with specific examples .. However, in this case - I don't understand how to write it specifically just for one data (if the end point is to retrieve all lists and it does retrieves for all data. Response : first object is array without optional array and second object is array with optional array and its values .. Note: if I remove the optional array in the builder - it doesnt verify this array at all and the test anyway passes. However, if I do add the optional array - test always fails because the intention of the end point is to retrieve for all data and not just one data (are we expected to write the builder with all array of responses?)
t
You do this with provider states
p
It is a common provider state in this case
t
test one: • State “titles don’t have titleLeads” • Request • Response expects no title leads test two: • State “titles have titleLeads” • Request • Response expects title leads
p
whatever you mentioned is applicable for my endpoint - get for titleLead1, get for titleLead2 etc .. (for which I have written two different states)
however for endpoint getalltitleLeads - above two states cant be separated
t
Why not?
p
as the response can have both
getallTitleLeads - returns both titles one with and one without
t
For get all, you could use the arrayContains matcher - one with and one without.
p
which means if the response is supposed to return two titles - I should have two array explicitly with arrayContains matcher ?
t
getallTitleLeads - returns both titles one with and one without
Yes. You could use two states: • “No titles have titleLeads” • “All titles have titleLeads” Or you could use “One title with titleLeads, and one title without titleLeads”
p
unfortunately getallTitleLeads - doesnt have any input param to return me only titles with titlesLeads and viceversa
t
No, no
not in the request
in the provider state
p
ok got you .. because we use mocking in the provider end - you saying use different provider state and mock the response to return two different states
t
Yes.
Or, have a single state that has both response types, and define your expectation explicitly.
titles: [exampleWithLeads, exampleNoLeads ]
p
hmm... unfortunately in my case - we are not using mocking for now in the provider end (I know its not 100% right, still.. ) as we are implementing contract testing for the existing microservices too - we pointing to live endpoint in the provider instead of mock (which doesnt give me responses for specific state).. and single state with both response types (this end point have got multiple such optional arrays and returns 100s of response with different combination - hence not easy to explicitly define the expectation)
t
In that case, I would define it with either the specific exact test data that you are setting up, or I would define it with the arrayContains matcher with both types of response object (I’m not familiar with the JVM DSL, so I can’t give you an exact answer there)
p
Sure nws … I got the idea though .. thanks
👍 1