Mocking GraphQL APIs in Integration Tests

Learn how to record and replay GraphQL API interactions in Spring Boot tests using StableMock. Handle query matching, variables, and schema validation automatically.

Testing GraphQL APIs can be trickier than REST. In REST, the URL path (/api/users/1) tells you what resource is being requested. In GraphQL, every request goes to the same URL (e.g., /graphql), and the intent is hidden inside the request body.

This makes traditional mocking hard because you can't just stub a URL pattern. You have to match the exact query payload.

StableMock simplifies this by recording the raw HTTP traffic. It doesn't care if it's REST, SOAP, or GraphQL—it just captures the interaction and replays it faithfully.

How to Test GraphQL Clients

No special configuration is needed! Just point your GraphQL client to the wiremock proxy using the standard @U annotation.

Example: Querying a Countries API

Here is a real-world example testing a Spring Boot application that queries the public Trevor Blades Countries API.

@U(urls = { "https://countries.trevorblades.com" })
@SpringBootTest
class GraphQLTest extends BaseStableMockTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void testGraphQLQuery() {
        // Define a standard GraphQL query
        String query = """
            {
              "query": "{ countries { code name } }"
            }
            """;

        // Send the POST request
        ResponseEntity<String> response = restTemplate.postForEntity(
            "/api/graphql-proxy",
            createRequest(query),
            String.class
        );

        // Verify the response contains real data from the recording
        assertTrue(response.getBody().contains("Andorra"));
    }
}

💡 Code Example: Check out GraphQLTest.java for the full working source code.

Handling Variables

GraphQL often uses variables to pass arguments. StableMock treats the variables object as part of the request body, so exact matching ensures your test scenarios don't bleed into each other.

@Test
void testQueryWithVariables() {
    // Query specifically for "US" country code
    String query = """
        {
          "query": "query GetCountry($code: ID!) { country(code: $code) { name } }",
          "variables": {
            "code": "US"
          }
        }
        """;

    client.send(query);
}

Best Practices for GraphQL Mocking

  • Use Operation Names: Always name your queries (e.g., query GetUser). This helps you identify recordings in the `mappings` folder.
  • Ignore Dynamic Variables: If your query includes a dynamically generated ID or timestamp in the variables block, use Automatic Detection to ignore matched fields.
  • Ignore Dynamic Variables: If your query includes a dynamically generated ID or timestamp in the variables block, use Automatic Detection to ignore matched fields.
  • Next: Learn how to handle Dynamic Fields and Timestamps.

    Stop Rewriting Mocks By Hand, Son

    Record once. Test offline forever.

    Join developers who've made the switch. Free forever. No credit card required.

    🌾 MIT License | 🚀 Open Source | 💯 Free Forever