Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit 1f22207

Browse files
authored
Merge pull request #348 from BlasiusSecundus/feature/test-response-improvements-vol-2
feat: improvements for GraphQL response testing facilities
2 parents f4d9732 + d197f0d commit 1f22207

File tree

5 files changed

+151
-11
lines changed

5 files changed

+151
-11
lines changed

graphql-spring-boot-test/build.gradle

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@
1919
dependencies {
2020
compile("org.springframework:spring-web:$LIB_SPRING_CORE_VER")
2121
compile("org.springframework.boot:spring-boot-starter-test:$LIB_SPRING_BOOT_VER")
22-
compile("com.fasterxml.jackson.core:jackson-databind:2.5.4")
23-
compile("com.jayway.jsonpath:json-path:2.3.0")
22+
compile("com.fasterxml.jackson.core:jackson-databind:2.10.2")
23+
compile("com.jayway.jsonpath:json-path:2.4.0")
2424
compileOnly("com.graphql-java:graphql-java:$LIB_GRAPHQL_JAVA_VER")
2525
compileOnly("com.graphql-java-kickstart:graphql-java-servlet:$LIB_GRAPHQL_SERVLET_VER")
26+
testImplementation("org.springframework.boot:spring-boot-starter-web:$LIB_SPRING_BOOT_VER")
2627
}
2728
repositories {
2829
mavenCentral()
2930
}
31+
32+
test {
33+
useJUnitPlatform()
34+
}

graphql-spring-boot-test/src/main/java/com/graphql/spring/boot/test/GraphQLResponse.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313

1414
public class GraphQLResponse {
1515

16-
private ResponseEntity<String> responseEntity;
17-
private ObjectMapper mapper;
18-
private ReadContext context;
16+
private final ResponseEntity<String> responseEntity;
17+
private final ObjectMapper mapper;
18+
private final ReadContext context;
1919

20-
public GraphQLResponse(ResponseEntity<String> responseEntity) {
20+
public GraphQLResponse(ResponseEntity<String> responseEntity, ObjectMapper objectMapper) {
2121
this.responseEntity = Objects.requireNonNull(responseEntity);
22-
this.mapper = new ObjectMapper();
22+
this.mapper = Objects.requireNonNull(objectMapper);
2323

2424
Objects.requireNonNull(responseEntity.getBody(),
2525
() -> "Body is empty with status " + responseEntity.getStatusCodeValue());
@@ -31,11 +31,11 @@ public JsonNode readTree() throws IOException {
3131
}
3232

3333
public String get(String path) {
34-
return context.read(path);
34+
return get(path, String.class);
3535
}
3636

3737
public <T> T get(String path, Class<T> type) {
38-
return context.read(path, type);
38+
return mapper.convertValue(context.read(path, Object.class), type);
3939
}
4040

4141
public <T> List<T> getList(String path, Class<T> type) {

graphql-spring-boot-test/src/main/java/com/graphql/spring/boot/test/GraphQLTestTemplate.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ public class GraphQLTestTemplate {
2727
private TestRestTemplate restTemplate;
2828
@Value("${graphql.servlet.mapping:/graphql}")
2929
private String graphqlMapping;
30+
@Autowired
31+
private ObjectMapper objectMapper;
3032

31-
private ObjectMapper objectMapper = new ObjectMapper();
3233
private HttpHeaders headers = new HttpHeaders();
3334

3435
private String createJsonQuery(String graphql, ObjectNode variables)
@@ -138,7 +139,7 @@ private GraphQLResponse post(String payload) {
138139

139140
private GraphQLResponse postRequest(HttpEntity<Object> request) {
140141
ResponseEntity<String> response = restTemplate.exchange(graphqlMapping, HttpMethod.POST, request, String.class);
141-
return new GraphQLResponse(response);
142+
return new GraphQLResponse(response, objectMapper);
142143
}
143144

144145
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.graphql.spring.boot.test;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
import org.junit.jupiter.api.DisplayName;
8+
import org.junit.jupiter.params.ParameterizedTest;
9+
import org.junit.jupiter.params.provider.Arguments;
10+
import org.junit.jupiter.params.provider.MethodSource;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.boot.test.context.SpringBootTest;
13+
import org.springframework.http.ResponseEntity;
14+
15+
import java.math.BigDecimal;
16+
import java.time.LocalDate;
17+
import java.util.Arrays;
18+
import java.util.List;
19+
import java.util.stream.Stream;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
23+
@SpringBootTest(classes = TestApplication.class)
24+
public class GraphQLResponseTest {
25+
26+
private static final String DATA_PATH = "$.data.test";
27+
28+
@Autowired
29+
private ObjectMapper objectMapper;
30+
31+
private static Stream<Arguments> testGetStringArguments() {
32+
return Stream.of(
33+
Arguments.of("{\"data\": {\"test\": 2}}", "2"),
34+
Arguments.of("{\"data\": {\"test\": \"2\"}}", "2"),
35+
Arguments.of("{\"data\": {\"test\": \"2020-02-23\"}}", "2020-02-23")
36+
);
37+
}
38+
39+
private static Stream<Arguments> testGetArguments() {
40+
return Stream.of(
41+
Arguments.of("{\"data\": {\"test\": \"2\"}}", Integer.class, 2),
42+
Arguments.of("{\"data\": {\"test\": \"2\"}}", String.class, "2"),
43+
Arguments.of("{\"data\": {\"test\": \"2\"}}", BigDecimal.class, new BigDecimal("2")),
44+
Arguments.of("{\"data\": {\"test\": \"2020-02-23\"}}", LocalDate.class, LocalDate.parse("2020-02-23")),
45+
Arguments.of("{\"data\": {\"test\": {\"foo\": \"fizzBuzz\", \"bar\": 13.8 }}}", FooBar.class,
46+
new FooBar("fizzBuzz", new BigDecimal("13.8")))
47+
);
48+
}
49+
50+
private static Stream<Arguments> testGetListArguments() {
51+
return Stream.of(
52+
Arguments.of("{\"data\": {\"test\": [\"2\", \"1\"]}}", Integer.class, Arrays.asList(2, 1)),
53+
Arguments.of("{\"data\": {\"test\": [\"2\", \"1\"]}}", String.class, Arrays.asList("2", "1")),
54+
Arguments.of("{\"data\": {\"test\": [\"2\", \"1\"]}}", BigDecimal.class,
55+
Arrays.asList(new BigDecimal("2"), new BigDecimal("1"))),
56+
Arguments.of("{\"data\": {\"test\": [\"2020-02-23\", \"2020-02-24\"]}}", LocalDate.class,
57+
Arrays.asList(LocalDate.parse("2020-02-23"), LocalDate.parse("2020-02-24"))),
58+
Arguments.of("{\"data\":{\"test\":[{\"foo\":\"fizz\",\"bar\":1.23},{\"foo\":\"buzz\",\"bar\":32.12}]}}",
59+
FooBar.class,
60+
Arrays.asList(
61+
new FooBar("fizz", new BigDecimal("1.23")),
62+
new FooBar("buzz", new BigDecimal("32.12"))
63+
)
64+
)
65+
);
66+
}
67+
68+
@DisplayName("Should get the JSON node's value as a String.")
69+
@ParameterizedTest
70+
@MethodSource("testGetStringArguments")
71+
public void testGetString(
72+
final String bodyString,
73+
final String expected
74+
) {
75+
//GIVEN
76+
final GraphQLResponse graphQLResponse = new GraphQLResponse(ResponseEntity.ok(bodyString), objectMapper);
77+
//WHEN
78+
final String actual = graphQLResponse.get(DATA_PATH);
79+
//THEN
80+
assertThat(actual).isEqualTo(expected);
81+
}
82+
83+
@DisplayName("Should get the JSON node's value as an instance of a specified class.")
84+
@ParameterizedTest
85+
@MethodSource("testGetArguments")
86+
public <T> void testGet(
87+
final String bodyString,
88+
final Class<T> clazz,
89+
final T expected
90+
) {
91+
//GIVEN
92+
final GraphQLResponse graphQLResponse = new GraphQLResponse(ResponseEntity.ok(bodyString), objectMapper);
93+
//WHEN
94+
final T actual = graphQLResponse.get(DATA_PATH, clazz);
95+
//THEN
96+
assertThat(actual).isInstanceOf(clazz).isEqualTo(expected);
97+
}
98+
99+
@DisplayName("Should get the JSON node's value as a List.")
100+
@ParameterizedTest
101+
@MethodSource("testGetListArguments")
102+
public <T> void testGetList(
103+
final String bodyString,
104+
final Class<T> clazz,
105+
final List<T> expected
106+
) {
107+
//GIVEN
108+
final GraphQLResponse graphQLResponse = new GraphQLResponse(ResponseEntity.ok(bodyString), objectMapper);
109+
//WHEN
110+
final List<T> actual = graphQLResponse.getList(DATA_PATH, clazz);
111+
//THEN
112+
assertThat(actual).containsExactlyElementsOf(expected);
113+
}
114+
115+
@Data
116+
@AllArgsConstructor
117+
@NoArgsConstructor
118+
private static class FooBar {
119+
private String foo;
120+
private BigDecimal bar;
121+
}
122+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.graphql.spring.boot.test;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class TestApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(TestApplication.class, args);
11+
}
12+
}

0 commit comments

Comments
 (0)