Hello everyone! Lets consider the following snippe...
# pact-jvm
a
Hello everyone! Lets consider the following snippet:
Copy code
void setup {
mockClient instantiation 
} 

public void pactTest(){
pact for a POST to the client 
}
This worked fine untill we implemented service descovery, and due to that, in setup is now an extra GET call to the mock server which generates Unexpected Request error. Debugging this, I discovered that the pactTest runs just fine, the post request is made after the get one and even if asserts are run and everything is ok, in the end it fails due to that unexpected request error. My question would be, is there any method to ignore the unexpected request, or to tell mock server how to respond to it, without adding it into the pact file ? Thanks in advance
m
Can you mock it out with the usual mocking tools?
I'm not aware of a way to exclude interactions, but you could post process the pact file to remove them (not ideal)
Is the discovery service on a different host/port?
a
Discovery call hits the target service, the mock in this situation, with GET on "/", otherwise, nothing different than a normal call to that service. As post process, we dont want it either. Trying to play with the mock server, I see that only interactions I can describe, ar the ones from @Pact annotated methods, nothing directly from setup
Also, I discovered that if I add the GET interaction in pact method definition , that will fail too because the discovery is done only at webClient startup in setup, so it wont be received bundled with the POST, and fail with request not matched. It tries to match the POST it receive at the actual call with the GET I describe in pact as being the first call.
t
I'm not sure I understand the service discovery pattern used here. Is the service being hit with the discovery request too? Isn't that a circular dependency?
Anyway, if it's done only at web client startup, and your client is stateless, you could maybe write a contract test for your discovery interaction, then start the client, then do the rest of the interactions
a
We are consumers, we fire the service descovery when we instantiate the webClient for the service we use. I'll try tomorrow to do what you suggested
t
usually service discovery is used to find where the services are - which you would need to know in order to hit
/
a
we use service descovery to see what actions we can perform next and what are the paths for it. Thats because our services are HATEOAS.
anyway, in simple terms, we as a consumers, send a GET request on the service when instantiating the webClient, which, as I mentioned, cause our pact test to fail with unexpected request, even though the pact test itself run successfully and the request is sent to mock server and the response is sent by it
t
Oh right! I think that isn't typically what people mean by service discovery, but I see what you mean now. Technically I guess HATEOAS is a REST pattern, but nowadays that just means “http and json”, so it's not a good way to talk about it, unfortunately.
How do you like it? I've always wanted to try it
m
Ok then my suggestion would be to mock out the initial service discovery call during instantiation, and have a dedicated pact test that only checks that
We want to avoid writing pact tests that test too many things at once
Fwiw the pact broker implements HATEOS via HAL (with some additions)
It works well, but it can confuse many people who just expect to hit predefined paths and makes things like documentation difficult, because there is poor support/tools for it (e.g. it doesn't fit the OAS model all that well)
t
With pact you might have a problem when it comes to the URLs, since pact will want to know what they are. How did this get solved for the broker, Matt? From provider state?
Oh, if you can inject your config, you could absolutely do that with fromProviderState, I reckon
m
How did this get solved for the broker, Matt? From provider state?
Because the Ruby app doesn’t support v3, it uses a “Hal relation proxy” - https://github.com/pact-foundation/pact_broker/blob/467780123bd717500f4317b34ade68471d2ff61a/spec/service_consumers/hal_relation_proxy_app.rb#L3-L5
It then uses this to augment the routes via middleware
FWIW there is a siren example Ron created in JS which shows how Pact can better support hypermedia APIs
Also a blog explaining why hypermedia APIs are actually hard to test with Pact (ironically). Despite it being Level 4 REST (or perhaps because of!) we don’t actually get many requests for supporting hypermedia APIs with Pact.