使用 quarkus-smallrye-graphql 进行单元测试
Unit Testing with quarkus-smallrye-graphql
在带有 quarkus-smallrye-graphql lib 的 quarkus 项目中,有没有办法像这样对 GraphQL 资源对象进行单元测试:
@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);
}
}
我希望能够在单元测试中发送 GraphQL 查询(没有身份验证 inactivated/or)以验证我的注释,但我没有找到任何记录的方法来执行此操作。
如果您可以使用纯 HTTP 请求进行通信,那么这样的方法就可以了
@QuarkusTest
public class ProductRepositoryTest {
@Test
public void testQuery() {
RestAssured.given()
.when()
.contentType("application/json")
.body("{ \"query\": \"{" +
" products {" +
" name" +
" price" +
" }" +
"}\"" +
"}")
.post("/graphql")
.then()
.statusCode(200)
.body("data.products", Matchers.not(Matchers.emptyArray()));
}
}
还可以选择使用来自 SmallRye GraphQL 的类型安全 GraphQL 客户端(请参阅我的存储库中的示例:https://github.com/jmartisk/mock-artifacts/tree/master/graphql/graphql-client)- 它应该可用于测试目的,即使它的级别非常高,所以您可能会丢失一些更细粒度的功能。
很快,也会有不同类型的客户端——动态客户端,但 SmallRye GraphQL 还不支持。
上次成功尝试:
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)));
注意:我已停用安全性以使单元测试正常工作。
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 中记录了一个很好的示例,我们可以编写此测试:
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");
}
}
最后很厉害的assert语句是基于
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.20.2</version>
<scope>test</scope>
在带有 quarkus-smallrye-graphql lib 的 quarkus 项目中,有没有办法像这样对 GraphQL 资源对象进行单元测试:
@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);
}
}
我希望能够在单元测试中发送 GraphQL 查询(没有身份验证 inactivated/or)以验证我的注释,但我没有找到任何记录的方法来执行此操作。
如果您可以使用纯 HTTP 请求进行通信,那么这样的方法就可以了
@QuarkusTest
public class ProductRepositoryTest {
@Test
public void testQuery() {
RestAssured.given()
.when()
.contentType("application/json")
.body("{ \"query\": \"{" +
" products {" +
" name" +
" price" +
" }" +
"}\"" +
"}")
.post("/graphql")
.then()
.statusCode(200)
.body("data.products", Matchers.not(Matchers.emptyArray()));
}
}
还可以选择使用来自 SmallRye GraphQL 的类型安全 GraphQL 客户端(请参阅我的存储库中的示例:https://github.com/jmartisk/mock-artifacts/tree/master/graphql/graphql-client)- 它应该可用于测试目的,即使它的级别非常高,所以您可能会丢失一些更细粒度的功能。 很快,也会有不同类型的客户端——动态客户端,但 SmallRye GraphQL 还不支持。
上次成功尝试:
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)));
注意:我已停用安全性以使单元测试正常工作。
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 中记录了一个很好的示例,我们可以编写此测试:
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");
}
}
最后很厉害的assert语句是基于
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.20.2</version>
<scope>test</scope>