diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java index 626a3547..b4010193 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java @@ -34,11 +34,11 @@ import com.jayway.jsonpath.TypeRef; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ResolvableType; -import org.springframework.graphql.support.DefaultGraphQlRequest; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.ResponseError; import org.springframework.graphql.client.GraphQlTransport; +import org.springframework.graphql.support.DefaultGraphQlRequest; import org.springframework.graphql.support.DocumentSource; import org.springframework.lang.Nullable; import org.springframework.test.util.AssertionErrors; @@ -377,8 +377,19 @@ final class DefaultGraphQlTester implements GraphQlTester { } @Override - public Path pathExists() { - this.delegate.doAssert(() -> this.pathHelper.hasJsonPath(this.delegate.jsonContent())); + public Path hasValue() { + this.delegate.doAssert(() -> this.pathHelper.exists(this.delegate.jsonContent())); + return this; + } + + @Override + public Path valueIsNull() { + Assert.isTrue(this.jsonPath.isDefinite(), "isNull applies only to JSONPath targeting a single value"); + this.delegate.doAssert(() -> { + Object value = this.pathHelper.evaluateJsonPath(this.delegate.jsonContent()); + AssertionErrors.assertNull( + "Expected null value at JSON path \"" + path + "\" but found " + value, value); + }); return this; } @@ -388,30 +399,6 @@ final class DefaultGraphQlTester implements GraphQlTester { return this; } - @Override - public Path valueExists() { - this.delegate.doAssert(() -> this.pathHelper.exists(this.delegate.jsonContent())); - return this; - } - - @Override - public Path valueDoesNotExist() { - this.delegate.doAssert(() -> this.pathHelper.doesNotExist(this.delegate.jsonContent())); - return this; - } - - @Override - public Path valueIsEmpty() { - this.delegate.doAssert(() -> this.pathHelper.assertValueIsEmpty(this.delegate.jsonContent())); - return this; - } - - @Override - public Path valueIsNotEmpty() { - this.delegate.doAssert(() -> this.pathHelper.assertValueIsNotEmpty(this.delegate.jsonContent())); - return this; - } - @Override public Entity entity(Class entityType) { D entity = this.delegate.read(this.jsonPath, new TypeRefAdapter<>(entityType)); diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java index 92c2e510..e1f5f432 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java @@ -213,44 +213,22 @@ public interface GraphQlTester { interface Path extends Traversable { /** - * Verify the given path exists, even if the value is {@code null}. + * Verify there is a {@code non-null} value or a non-empty list at the current path. * @return the same {@code Path} spec for further assertions */ - Path pathExists(); + Path hasValue(); /** - * Assert the given path does not {@link #pathExists() exist}. + * Verify there is a {@code null} value at the current path. + */ + Path valueIsNull(); + + /** + * Verify the current path does not exist. * @return the same {@code Path} spec for further assertions */ Path pathDoesNotExist(); - /** - * Assert a value exists at the given path where the value is any {@code non-null} - * value, possibly an empty array or map. - * @return the same {@code Path} spec for further assertions - */ - Path valueExists(); - - /** - * Assert a value does not {@link #valueExists() exist} at the given path. - * @return the same {@code Path} spec for further assertions - */ - Path valueDoesNotExist(); - - /** - * Assert the value at the given path does exist but is empty as defined - * in {@link org.springframework.util.ObjectUtils#isEmpty(Object)}. - * @return the same {@code Path} spec for further assertions - * @see org.springframework.util.ObjectUtils#isEmpty(Object) - */ - Path valueIsEmpty(); - - /** - * Assert the value at the given path is not {@link #valueIsEmpty() empty}. - * @return the same {@code Path} spec for further assertions - */ - Path valueIsNotEmpty(); - /** * Convert the data at the given path to the target type. * @param entityType the type to convert to diff --git a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java index 349feb9c..91aeaadb 100644 --- a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java +++ b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java @@ -40,38 +40,61 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; public class GraphQlTesterTests extends GraphQlTesterTestSupport { @Test - void pathAndValueExist() { + void hasValue() { String document = "{me {name, friends}}"; setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}"); GraphQlTester.Response response = graphQlTester().document(document).execute(); + response.path("me.name").hasValue(); + response.path("me.friends").hasValue(); - response.path("me.name").pathExists().valueExists(); - response.path("me.friends").pathExists().valueExists(); - response.path("hero").pathDoesNotExist().valueDoesNotExist(); + assertThatThrownBy(() -> response.path("hero").hasValue()) + .hasMessageContaining("No value at JSON path \"$['data']['hero']"); assertThat(request().getDocument()).contains(document); } @Test - void valueIsEmpty() { + void valueIsNull() { String document = "{me {name, friends}}"; - setMockResponse("{\"me\": {\"name\":null, \"friends\":[]}}"); + setMockResponse("{\"me\": {\"name\":null, \"friends\":null}}"); GraphQlTester.Response response = graphQlTester().document(document).execute(); - response.path("me.name").valueIsEmpty(); - response.path("me.friends").valueIsEmpty(); + response.path("me.name").valueIsNull(); + response.path("me.friends").valueIsNull(); - assertThatThrownBy(() -> response.path("hero").valueIsEmpty()) - .as("Path does not even exist") - .hasMessageContaining("No value at JSON path \"$['data']['hero']"); + assertThatThrownBy(() -> response.path("me").valueIsNull()) + .hasMessageContaining("Expected null value at JSON path"); assertThat(request().getDocument()).contains(document); } + @Test + void valueIsEmptyList() { + + String document = "{me {name, friends}}"; + setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}"); + + GraphQlTester.Response response = graphQlTester().document(document).execute(); + response.path("me.friends").hasValue().entityList(MovieCharacter.class).hasSize(0); + } + + @Test + void pathDoesNotExist() { + String document = "{me {name, friends}}"; + setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}"); + + GraphQlTester.Response response = graphQlTester().document(document).execute(); + + response.path("hero").pathDoesNotExist(); + + assertThatThrownBy(() -> response.path("me.name").pathDoesNotExist()) + .hasMessageContaining("Expected no value at JSON path"); + } + @Test void matchesJson() {