Édouard Lopez
Édouard Lopez

Reputation: 43401

How to return a bad request (400, 500) with Pact in Go?

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:

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?

Upvotes: 2

Views: 323

Answers (1)

Matthew Fellows
Matthew Fellows

Reputation: 4065

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.

Upvotes: 2

Related Questions