Search code examples
angularjestjspact

Test GraphQL endpoint with PactV3 fails (PactV3 500 Internal Server Error)


I try to create a Pact on the consumer side with Pact-JS. In PactJS v3, the .withQuery method seemed to be removed and generall support for GraphQL testing is not available. Tough it should be possible to either use the mentioned GraphQLInteraction interaction or to test the plain body of the POST request I guess, but I couldn't figure out how, since as soon as I add a body to the .requestWith method, I get the error:

Http failure response for http://... 500 Internal Server Error

The problem is the body property in the withRequest method. Without the property the mock server throws no error but the Pact of course doesn't include a request body and therefore is quite useless.

.withRequest({
  method: 'POST',
  path: `/product/graphql`,
  headers: {
    'Content-Type': 'application/json',
    Accept: "application/json",
  },

  /*
   * Adding a body to the request fails with:
   * `Http failure response for http://127.0.0.1:4000/product/graphql: 500 Internal Server Error`
   *
   * The goal is to have the request body in the created Pact, because without it, it is
   * quite useless.
   */
  // body: requestBody,                                     // fails
  // body: MatchersV3.like(requestBody),                    // fails
  // body: MatchersV3.string(JSON.stringify(requestBody)),  // fails
})

I created a GIT repository with a minimal example for the attempt with the body. As Karma support was deprecated with Pact v10, the repo also includes the switch to Jest.


Solution

  • It looks like you're missing the operationName from the request.

    The logs hint at this:

    [2022-08-13T11:48:06Z DEBUG pact_matching] --> Mismatches: [BodyMismatch { path: "$", expected: Some(b"[\"query\",\"variables\"]"), actual: Some(b"[\"operationName\",\"query\",\"variables\"]"), mismatch: "Expected a Map with keys query, variables but received one with keys operationName, query, variables" }]
    [2022-08-13T11:48:06Z DEBUG pact_mock_server::hyper_server] Request did not match: Request did not match - HTTP Request ( method: POST, path: /product/graphql, query: None, headers: Some({"Content-Type": ["application/json"], "Accept": ["application/json"]}), body: Present(68 bytes, application/json) )    0) $ -> Expected a Map with keys query, variables but received one with keys operationName, query, variables
    

    The correct query to send as the body is:

    const requestBody = { "operationName": "product", "query":"{ product { data { idProduct name } } }", "variables": null }
    

    There is an issue in Pact JS which is not helpfully printing this for you, as the test itself is failing. The next release of Pact JS should print a (more helpful) error like this for you:

      ● Product Service › Given there are already some products in the database › should get a list of existing products
    
        Test failed for the following reasons:
    
          Mock server failed with the following mismatches:
    
            0) The following request was incorrect:
    
                    POST /product/graphql
    
                     1.0 Expected a Map with keys query, variables but received one with keys operationName, query, variables