Add option for expected errors to GraphQlTester

Closes: gh-175
This commit is contained in:
Rossen Stoyanchev
2021-11-15 15:43:16 +00:00
parent 5c0b32912a
commit 0df1884500
4 changed files with 78 additions and 13 deletions

View File

@@ -203,13 +203,19 @@ class DefaultGraphQlTester implements GraphQlTester {
this.assertDecorator.accept(task);
}
void filterErrors(@Nullable Predicate<GraphQLError> predicate) {
boolean filterErrors(@Nullable Predicate<GraphQLError> predicate) {
boolean filtered = false;
if (predicate != null) {
this.errors.forEach((error) -> {
// Error marked "filtered" if true
error.applyErrorFilterPredicate(predicate);
});
for (TestGraphQlError error : this.errors) {
filtered |= error.apply(predicate);
}
}
return filtered;
}
void expectErrors(@Nullable Predicate<GraphQLError> predicate) {
boolean filtered = filterErrors(predicate);
this.assertDecorator.accept(() -> AssertionErrors.assertTrue("No matching errors.", filtered));
}
void consumeErrors(Consumer<List<GraphQLError>> consumer) {
@@ -265,6 +271,12 @@ class DefaultGraphQlTester implements GraphQlTester {
return this;
}
@Override
public ErrorSpec expect(Predicate<GraphQLError> predicate) {
this.responseContainer.expectErrors(predicate);
return this;
}
@Override
public TraverseSpec verify() {
this.responseContainer.verifyErrors();

View File

@@ -90,10 +90,8 @@ public interface GraphQlTester {
interface Builder<T extends Builder<T>> {
/**
* Add a global filter for expected errors. All errors that match the
* given predicate are treated as expected and ignored on
* {@link GraphQlTester.ErrorSpec#verify()} or when
* {@link TraverseSpec#path(String) traversing} to a data path.
* Configure a global {@link ErrorSpec#filter(Predicate) filter} that
* applies to all requests.
* @param predicate the error filter to add
* @return the same builder instance
*/
@@ -450,14 +448,32 @@ public interface GraphQlTester {
interface ErrorSpec {
/**
* Add a filter for expected errors. All errors that match the predicate are
* treated as expected and ignored on {@link #verify()} or when
* Use this to filter out errors that are expected and can be ignored.
* This can be useful for warnings or other notifications returned along
* with the data.
* <p>The configured filters are applied to all errors. Those that match
* are treated as expected and are ignored on {@link #verify()} or when
* {@link TraverseSpec#path(String) traversing} to a data path.
* <p>In contrast to {@link #expect(Predicate)}, filters do not have to
* match any errors, and don't imply that the errors must be present.
* @param errorPredicate the error filter to add
* @return the same spec to add more filters before {@link #verify()}
*/
ErrorSpec filter(Predicate<GraphQLError> errorPredicate);
/**
* Use this to declare errors that are expected.
* <p>Errors that match are treated as expected and are ignored on
* {@link #verify()} or when {@link TraverseSpec#path(String) traversing}
* to a data path.
* <p>In contrast to {@link #filter(Predicate)}, use of this option
* does imply that errors are present or else an {@link AssertionError}
* is raised.
* @param errorPredicate the predicate for the expected error
* @return the same spec to add more filters or expected errors
*/
ErrorSpec expect(Predicate<GraphQLError> errorPredicate);
/**
* Verify there are either no errors or that there no unexpected errors that have
* not been {@link #filter(Predicate) filtered out}.

View File

@@ -148,9 +148,12 @@ final class TestGraphQlError implements GraphQLError {
/**
* Mark this error as expected if it matches the predicate.
* @param predicate the error predicate
* @return whether the predicate matched
*/
void applyErrorFilterPredicate(Predicate<GraphQLError> predicate) {
this.expected |= predicate.test(this);
boolean apply(Predicate<GraphQLError> predicate) {
boolean match = predicate.test(this);
this.expected |= match;
return match;
}
@Override

View File

@@ -276,6 +276,40 @@ public class GraphQlTesterTests {
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
}
@Test
void errorsExpected() throws Exception {
String query = "{me {name, friends}}";
setResponse(
GraphqlErrorBuilder.newError().message("some error").build(),
GraphqlErrorBuilder.newError().message("some other error").build());
this.graphQlTester.query(query)
.execute()
.errors()
.expect((error) -> error.getMessage().startsWith("some "))
.verify()
.path("me")
.pathDoesNotExist();
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
}
@Test
void errorsExpectedButNotFound() throws Exception {
String query = "{me {name, friends}}";
setResponse(
GraphqlErrorBuilder.newError().message("some error").build(),
GraphqlErrorBuilder.newError().message("some other error").build());
assertThatThrownBy(() ->
this.graphQlTester.query(query)
.execute()
.errors().expect((error) -> error.getMessage().startsWith("another ")))
.hasMessageStartingWith("No matching errors.");
}
@Test
void errorsConsumed() throws Exception {