CodeGym /Courses /Module 5. Spring /Lecture 297: Testing GraphQL API

Lecture 297: Testing GraphQL API

Module 5. Spring
Level 16 , Lesson 6
Available

Any developer knows that the fewer bugs in an API, the fewer support calls you'll get. Testing isn't just checking that your system works — it's how you prove it works the way it's supposed to. Testing a GraphQL API is especially important:

  • Verify query and mutation logic: make sure your queries execute correctly and mutations change data the way they should.
  • Ensure security: check that users can only access the data they're supposed to.
  • Performance: make sure the API handles requests quickly and efficiently even under load.
  • Stability: ensure that code changes don't break existing functionality.

Approaches to testing GraphQL API

Like any application, testing a GraphQL API can be split into several levels:

Unit tests

These are tests for individual components of the app, such as Data Fetchers, Resolvers, or services. The goal is to test them in isolation from other components.

Example:


@Test
void testFetchUserById() {
    // Given
    UUID userId = UUID.randomUUID();
    User mockUser = new User(userId, "John", "Doe");
    when(userRepository.findById(userId)).thenReturn(Optional.of(mockUser));

    // When
    User result = userService.fetchUserById(userId);

    // Then
    assertEquals(mockUser, result);
}

2. Integration tests

Here we test the interaction between different parts of the app — for example, calling a GraphQL query and having it handled by its Resolver.

Tools: Spring Boot Test, MockMvc.

Example:


@Test
void testGraphQLQuery() throws Exception {
    String query = "{ user(id: \"1\") { firstName lastName } }";

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"query\":\"" + query + "\"}"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.user.firstName").value("John"))
            .andExpect(jsonPath("$.data.user.lastName").value("Doe"));
}

3. Contract testing

Used to verify interactions between microservices. For example, if one microservice provides a GraphQL API and another consumes it, it's important to ensure agreements about request and response formats are respected.

Tool: Pact.

4. Load testing

This lets you check how the API handles a large number of simultaneous requests.

Tool: k6.


Using JUnit to test GraphQL

JUnit is the standard testing framework in Java, and it's great for verifying GraphQL business logic. Let's start with a simple Resolver test.

Example Resolver test:


@Test
void testResolveQuery() {
    // Given
    String query = "{ user(id: \"1\") { firstName, lastName } }";
    ExecutionInput executionInput = ExecutionInput.newExecutionInput()
            .query(query)
            .build();

    // When
    ExecutionResult executionResult = graphQL.execute(executionInput);

    // Then
    Map<String, Object7>) data.get("user")).get("firstName"));
}

Here we create a GraphQL query and check that the data comes back correctly.


Practice: testing GraphQL API with JUnit and MockMvc

MockMvc is a powerful tool for integration testing Spring apps, including GraphQL APIs.

1. Setting up tests

First, make sure you have Spring Boot Test configured. To test GraphQL requests via MockMvc you need to set up your controller.

Example configuration:

@Autowired
private MockMvc mockMvc;

2. Writing a test scenario

Testing a query to get a user:


@Test
void testUserQuery() throws Exception {
    String query = "{ user(id: \"1\") { firstName, lastName } }";

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"query\":\"" + query + "\"}"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.user.firstName").value("John"))
            .andExpect(jsonPath("$.data.user.lastName").value("Doe"));
}

Here we check that the request works and returns the expected data.


Testing complex queries and mutations

In more complex scenarios the API may return nested objects or perform data mutations.

Example complex query:


@Test
void testComplexQuery() throws Exception {
    String query = "{ user(id: \"1\") { firstName, posts { title, content } } }";

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"query\":\"" + query + "\"}"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.user.firstName").value("John"))
            .andExpect(jsonPath("$.data.user.posts[0].title").value("Post 1"))
            .andExpect(jsonPath("$.data.user.posts[0].content").value("Content 1"));
}

Example mutation:


@Test
void testCreateUserMutation() throws Exception {
    String mutation = "mutation { createUser(input: { firstName: \"Jane\", lastName: \"Doe\" }) { id, firstName, lastName } }";

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"query\":\"" + mutation + "\"}"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.createUser.firstName").value("Jane"))
            .andExpect(jsonPath("$.data.createUser.lastName").value("Doe"));
}

Testing security and performance

Check that users without the necessary permissions can't execute certain requests.

Example permission check:


@Test
@WithMockUser(roles = "ADMIN")
void testAdminAccess() throws Exception {
    String query = "{ adminData { sensitiveInfo } }";

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"query\":\"" + query + "\"}"))
            .andExpect(status().isOk());
}

@Test
@WithMockUser(roles = "USER")
void testUnauthorizedAccess() throws Exception {
    String query = "{ adminData { sensitiveInfo } }";

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"query\":\"" + query + "\"}"))
            .andExpect(status().isForbidden());
}

Use tools like k6 to check performance:

k6 run --vus 10 --iterations 100 script.js

Conclusion

Now you've got the knowledge and examples to write tests for a GraphQL API. You can verify both the logic of individual components and the interactions between different parts of the system. Pay special attention to security and performance — those are key aspects in real-world development.

All your tests will help catch bugs before they hit production. That means: peaceful sleep and grateful users!

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION