CodeGym /Cursos /Módulo 5. Spring /Lección 298: Práctica: Testear GraphQL API usando JUnit y...

Lección 298: Práctica: Testear GraphQL API usando JUnit y MockMvc

Módulo 5. Spring
Nivel 16 , Lección 7
Disponible

Probar GraphQL API es una etapa importante del desarrollo; garantiza la corrección de los esquemas, las consultas, las mutations y la seguridad de los datos. Vamos a usar JUnit y MockMvc — herramientas que llevan tiempo demostrando su valía en las pruebas de aplicaciones Spring. La particularidad de testear GraphQL API es la necesidad de verificar las consultas de forma parecida a REST, pero teniendo en cuenta las características propias de GraphQL, como seleccionar solo los campos solicitados y gestionar estructuras anidadas complejas.


Configuración del entorno de pruebas para GraphQL

Antes de comenzar con las pruebas hay que configurar correctamente el entorno de testing. Añadiremos las dependencias necesarias, prepararemos los datos de prueba y configuraremos MockMvc para trabajar con peticiones GraphQL.

Añadimos dependencias en pom.xml

Asegúrate de tener las siguientes dependencias:


<dependencies>
    <!-- Dependencias para GraphQL -->
    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphql-spring-boot-starter</artifactId>
        <version>15.0.0</version>
    </dependency>
    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphql-java-tools</artifactId>
        <version>11.1.0</version>
    </dependency>

    <!-- Dependencias para pruebas -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.graphql</groupId>
        <artifactId>spring-graphql-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2. Configuración del contexto de pruebas

Usamos la anotación @SpringBootTest para levantar el contexto de la aplicación durante las pruebas. Además, configuramos MockMvc para enviar las peticiones.


@SpringBootTest
@AutoConfigureMockMvc
public class GraphQLTest {
    @Autowired
    private MockMvc mockMvc;
}

Escribir escenarios de prueba

Vamos a escribir algunos tests para comprobar nuestro GraphQL API. Probaremos queries, mutations y el manejo de errores.

1. Test de una consulta GraphQL

Supongamos que tenemos el esquema schema.graphql:


type Query {
    getBook(id: ID!): Book
}

type Book {
    id: ID!
    title: String
    author: String
}

Probamos la consulta para obtener un libro por ID:


query {
    getBook(id: "1") {
        id
        title
        author
    }
}

Método de prueba para esa consulta:


@Test
void testGetBookQuery() throws Exception {
    String query = """
        {
            "query": "query { getBook(id: \\"1\\") { id title author } }"
        }
    """;

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content(query))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.getBook.id").value("1"))
            .andExpect(jsonPath("$.data.getBook.title").value("GraphQL for Beginners"))
            .andExpect(jsonPath("$.data.getBook.author").value("John Doe"));
}

En el código:

  • En query formamos el cuerpo de la petición GraphQL en formato JSON.
  • Usamos MockMvc para enviar un POST a /graphql.
  • Comprobamos el estado de la respuesta con status().isOk().
  • Verificamos los datos de la respuesta con jsonPath.

2. Testeo de mutation

Si tenemos una mutation para añadir un nuevo libro:


mutation {
    addBook(input: { title: "Spring Boot with GraphQL", author: "Jane Doe" }) {
        id
        title
        author
    }
}

Método de prueba para la mutation:


@Test
void testAddBookMutation() throws Exception {
    String mutation = """
        {
            "query": "mutation { addBook(input: { title: \\"Spring Boot with GraphQL\\", author: \\"Jane Doe\\" }) { id title author } }"
        }
    """;

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content(mutation))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.addBook.title").value("Spring Boot with GraphQL"))
            .andExpect(jsonPath("$.data.addBook.author").value("Jane Doe"));
}

Fíjate que comprobamos los campos que devuelve la mutation. Esto ayuda a asegurar que la mutation funciona correctamente.


3. Testeo de errores

Las GraphQL APIs suelen devolver errores en el campo errors. Probemos qué pasa si el libro solicitado no se encuentra:


query {
    getBook(id: "999") {
        id
        title
        author
    }
}

Método de prueba:


@Test
void testGetBookNotFound() throws Exception {
    String query = """
        {
            "query": "query { getBook(id: \\"999\\") { id title author } }"
        }
    """;

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content(query))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.errors").exists())
            .andExpect(jsonPath("$.errors[0].message").value("Book not found"));
}

Aquí comprobamos que el campo errors existe y que el error contiene el mensaje "Book not found".


Testeo de consultas complejas

Las consultas GraphQL complejas pueden incluir campos anidados y varios niveles de datos. Por ejemplo:

query {
    getBook(id: "1") {
        id
        title
        author
        reviews {
            reviewer
            comment
        }
    }
}

Probamos esa consulta de forma similar — verificando las estructuras JSON anidadas:


@Test
void testGetBookWithReviews() throws Exception {
    String query = """
        {
            "query": "query { getBook(id: \\"1\\") { id title author reviews { reviewer comment } } }"
        }
    """;

    mockMvc.perform(post("/graphql")
            .contentType(MediaType.APPLICATION_JSON)
            .content(query))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.getBook.reviews[0].reviewer").value("Alice"))
            .andExpect(jsonPath("$.data.getBook.reviews[0].comment").value("Great book!"));
}

Testeo de seguridad

Si usamos autenticación por token (por ejemplo, JWT), podemos añadir el token en el header:


@Test
void testAuthorizedQuery() throws Exception {
    String query = """
        {
            "query": "query { getBook(id: \\"1\\") { id title author } }"
        }
    """;

    mockMvc.perform(post("/graphql")
            .header(HttpHeaders.AUTHORIZATION, "Bearer mock-jwt-token")
            .contentType(MediaType.APPLICATION_JSON)
            .content(query))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.getBook.title").value("GraphQL for Beginners"));
}

Resumen

Testear GraphQL API con JUnit y MockMvc es una forma potente de asegurar la estabilidad y la corrección de tu aplicación. Hemos visto cómo testear queries, mutations, errores, estructuras anidadas complejas y seguridad. Estos enfoques te ayudarán a preparar tu aplicación con confianza para producción.

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