I'm working in the adoption of Pact in my company, but on Golang, we hit a hurdle on the basic case where a consumer as 2 states for one endpoint:
- Given("A product with id 1 exists").
- Given("A product with id 2 doesn't exists").
Our trouble is on the doesn't exists case.
Consumer
mockProvider.AddInteraction().
Given("The product with ID 66 doesn't exists").
UponReceiving("a request Product 66").
WithRequest(http.MethodGet, S("/api/v1/product/66")).
WillRespondWith(http.StatusNotFound).
Provider
func TestContract(t *testing.T) {
SetLogLevel("TRACE")
verifier := HTTPVerifier{}
err := verifier.VerifyProvider(t, VerifyRequest{
ProviderBaseURL: "http://localhost:8080",
Provider: "ms.pact-provider-example-for-go",
ProviderVersion: "example", // os.Getenv("APP_SHA"),
BrokerURL: "https://…", // os.Getenv("PACT_BROKER_BASE_URL"),
PublishVerificationResults: false,
StateHandlers: StateHandlers{
"A product with id 1 exists": func(setup bool, s ProviderStateV3) (ProviderStateV3Response, error) {
…
return response, nil
},
"A product with id 2 doesn't exists": func(setup bool, s ProviderStateV3) (ProviderStateV3Response, error) {
// ???
},
},
})
require.NoError(t, err)
}
Question
How can we return a bad request reponse as ProviderStateV3Response
is a map interface?
CodePudding user response:
StateHandlers
don't exist to change the response directly (that could impact the validity of the test), they exist to modify the internal state of the provider for the current test. The use the state name (and optionally, parameters) to determine what state should be configured.
When the test executes, the provider should execute its usual code with that state in place, and respond accordingly.
StateHandlers: StateHandlers{
"A product with id 1 exists": func(setup bool, s ProviderStateV3) (ProviderStateV3Response, error) {
// modify internal state of the provider, so that product with ID 1 exists in the database
return response, nil
},
"A product with id 2 doesn't exists": func(setup bool, s ProviderStateV3) (ProviderStateV3Response, error) {
// modify internal state of the provider, so that product with ID 2 does not exist in the database
},
},
There are examples in the repository, such as https://github.com/pact-foundation/pact-go/blob/master/examples/mux/provider/user_service_test.go#L94-L120.
States are abstract - it doesn't imply how the state is configured. It could achieve the state transition in multiple ways such as updating a database or configuring a stub etc.