JavaRush /Курси /Модуль 5. Spring /Лекція 298: Практика: Тестування GraphQL API з використан...

Лекція 298: Практика: Тестування GraphQL API з використанням JUnit і MockMvc

Модуль 5. Spring
Рівень 16 , Лекція 7
Відкрита

Тестування GraphQL API — важливий етап розробки, воно забезпечує коректність роботи схеми, запитів, мутацій та безпеку даних. Ми будемо використовувати JUnit і MockMvc — інструменти, які вже давно зарекомендували себе при тестуванні Spring додатків. Унікальність тестування GraphQL API в тому, що потрібно перевіряти запити подібно до REST, але з урахуванням особливостей GraphQL, таких як вибір тільки запитаних полів і складні вкладені структури.


Налаштування тестового оточення для GraphQL

Перед початком тестування потрібно правильно налаштувати тестове середовище. Ми додамо всі потрібні залежності, налаштуємо тестові дані і підготуємо MockMvc для роботи з GraphQL-запитами.

Додаємо залежності в pom.xml

Переконайтеся, що у вас підключені наступні залежності:


<dependencies>
    <!-- Залежності для 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>

    <!-- Залежності для тестування -->
    <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. Налаштування тестового контексту

Використовуємо анотацію @SpringBootTest, щоб підняти контекст додатка під час тестів. Крім того, підключимо MockMvc для відправки запитів.


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

Написання тестових сценаріїв

Давайте напишемо кілька тестів для перевірки нашого GraphQL API. Ми будемо тестувати запити, мутації та обробку помилок.

1. Тестування GraphQL запиту

Припустимо, у нас є схема schema.graphql:


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

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

Ми тестуємо запит, щоб отримати книгу за ID:


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

Тестовий метод для цього запиту:


@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"));
}

У коді:

  • У query ми формуємо тіло GraphQL-запиту у форматі JSON.
  • Використовуємо MockMvc для відправки POST-запиту на /graphql.
  • Перевіряємо статус відповіді за допомогою status().isOk().
  • Перевіряємо дані відповіді через jsonPath.

2. Тестування мутації

Якщо в нас є мутація для додавання нової книги:


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

Тестовий метод для мутації:


@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"));
}

Зверніть увагу, що ми перевіряємо поля, які повертає мутація. Це допомагає переконатися, що мутація працює коректно.


3. Тестування помилок

GraphQL API часто повертає помилки в полі errors. Давайте протестуємо, що станеться, якщо запитувана книга не знайдена:


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

Тестовий метод:


@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"));
}

Тут ми перевіряємо, що поле errors присутнє, і помилка містить повідомлення "Book not found".


Тестування складних запитів

Складні GraphQL-запити можуть включати вкладені поля і кілька рівнів даних. Наприклад:

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

Тестуємо цей запит аналогічно — перевіряємо вкладені структури JSON:


@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!"));
}

Тестування безпеки

Якщо в нас є аутентифікація через токен (наприклад, JWT), можемо додати токен у заголовок:


@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"));
}

Підсумок

Тестування GraphQL API з використанням JUnit і MockMvc — це потужний спосіб забезпечити стабільність і коректність вашого додатка. Ми розглянули тестування запитів, мутацій, помилок, складних вкладених структур і безпеки. Ці підходи допоможуть вам впевнено готувати додаток до продакшену.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ