'Unit Testing with quarkus-smallrye-graphql

In a quarkus project with quarkus-smallrye-graphql lib, is there a way to unit test a GraphQL resource object like this one :

@GraphQLApi
public class ProductResource {

    @Inject
    private ProductRepository productRepository;

    @Query("products")
    @Description("Get all Products")
    @RolesAllowed({"USER","ADMIN"})
    public List<Product> findAll() {
        return this.productRepository.findAll().list();
    }

    @Mutation
    @Description("Create a new Product")
    @RolesAllowed("ADMIN")
    public Boolean createProduct(String name, Double price) {
        return this.productRepository.createProduct(name, price);
    }
}

I want to be able to send a GraphQL query (with Authentication inactivated/or not) in unit testing in order to validate my annotations but I don't find any documented way to do it.



Solution 1:[1]

Last successful try :

  RestAssured.given()
                .when()
                .contentType("application/json")
                .body("{ \"query\": \"{" +
                        "  products {" +
                        "    name" +
                        "    price" +
                        "  }" +
                        "}\"" +
                        "}")
                .post("/graphql")
                .then().log().ifValidationFails()
                .statusCode(200)
                .body("data.products.name", Matchers.hasItems("Ten", "Twenty"))
                .body("data.products.price", Matchers.hasItems(Matchers.equalTo(10f), Matchers.equalTo(20f)));

NB: I've inactivated the security to make the unit tests work.

Solution 2:[2]

There is a great example documented at https://claudioaltamura.de/api/graphql-apis-with-quarkus with source code at https://github.com/claudioaltamura/quarkus-graphql-superheroes. Based on that when using the official demo code at https://quarkus.io/guides/smallrye-graphql we can write this test:


import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.text.StringEscapeUtils;
import org.junit.jupiter.api.Test;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;

class GqlTestHelpers {

    @SneakyThrows
    public static String loadQueryAsJson(String resource) {
        Path path = Paths.get(resource);
        String allLines = Files.readAllLines(path).stream().collect(Collectors.joining("\n"));
        val quotedQuery = StringEscapeUtils.escapeJson(allLines);
        val json = "{ \"query\": \"" + quotedQuery + "\"}";
        return json;
    }
}

@QuarkusTest
@Slf4j
public class FilmResourceTest {

    @Test
    public void testQuery() {

        val query = GqlTestHelpers.loadQueryAsJson("src/test/resources/allFilms.gql");

        final Response response = RestAssured.given()
                .contentType(ContentType.JSON)
                .body(query)
                .when()
                .post("/graphql")
                .then()
                .assertThat()
                .statusCode(200)
                .and()
                .extract()
                .response();

        log.info(response.body().prettyPrint());

        final List<Film> films = response.jsonPath().getList("data.allFilms", Film.class);
        log.info(films.toString());

        assertThat(films)
                .isNotEmpty()
                .hasSize(3)
                .extracting(Film::getTitle)
                .contains("A New Hope", "The Empire Strikes Back", "Return Of The Jedi");
    }
}

The very powerful assert statement at the end is based on

    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.20.2</version>
      <scope>test</scope>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fabien MIFSUD
Solution 2 simbo1905