Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterise DataLoaderTest on DataLoader #153

Merged

Conversation

AlexandreCarlton
Copy link
Collaborator

The existing DataLoaderTest covers a very large range of test cases which will be very useful to validate what is being added in #148.

To allow new *Publisher DataLoaders to leverage this without copy-pasting, we make DataLoaderTest a parameterised test, using two DataLoader variants:

  • the stock 'List' DataLoader.
  • the 'Mapped' DataLoader.

Most of the tests in DataLoaderTest have been retrofitted for this parameterisation, resulting in:

  • deduplicated code (many of the MappedDataLoader tests have the same test cases, almost line-for-line).
  • increased coverage of the MappedDataLoader, bolstering confidence in subsequent changes (rather than relying on the author understanding how everything is put together internally).

The existing `DataLoaderTest` covers a very large range of test cases
which will be very useful to validate what is being added in graphql-java#148.

To allow new `*Publisher` `DataLoader`s to leverage this without
copy-pasting, we make `DataLoaderTest` a parameterised test, using two
`DataLoader` variants:

 - the stock 'List' `DataLoader`.
 - the 'Mapped' `DataLoader`.

Most of the tests in `DataLoaderTest` have been retrofitted for this
parameterisation, resulting in:

 - deduplicated code (many of the `MappedDataLoader` tests have the same
   test cases, almost line-for-line).
 - increased coverage of the `MappedDataLoader`, bolstering confidence
   in subsequent changes (rather than relying on the author
   understanding how everything is put together internally).

private static <K, V> DataLoader<K, V> idMapLoaderBlowsUps(
DataLoaderOptions options, List<Collection<K>> loadCalls) {
return newDataLoader((keys) -> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this was testing a MappedBatchLoader - we would have needed newMappedDataLoader for this.



@Test
public void basic_map_batch_loading() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved this to DataLoaderTest - all other test cases here were identical to the ones found in DataLoaderTest.

@@ -78,9 +88,36 @@ public void should_Build_a_really_really_simple_data_loader() {
}

@Test
public void should_Support_loading_multiple_keys_in_one_call() {
public void basic_map_batch_loading() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved across from DataLoaderMapBatchLoaderTest.

}

@ParameterizedTest
@MethodSource("dataLoaderFactories")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now run this test (and any test annotated with @MethodSource("dataLoaderFactories")) with all the TestDataLoaderFactory instances returned from the static method dataLoaderFactories.

private static Stream<Arguments> dataLoaderFactories() {
return Stream.of(
Arguments.of(Named.of("List DataLoader", new ListDataLoaderFactory())),
Arguments.of(Named.of("Mapped DataLoader", new MappedDataLoaderFactory()))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, if we wish to test more implementations of a DataLoader, we need only drop in a new entry here, and we get instant coverage.

return TestKit.futureError();
}, options);
public interface TestDataLoaderFactory {
<K, V> DataLoader<K, V> idLoader(DataLoaderOptions options, List<Collection<K>> loadCalls);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods are identical to what was already present for the List DataLoader; I've moved across/added new ones for the Mapped implementation.

AtomicBoolean success = new AtomicBoolean();
DataLoader<Integer, Integer> identityLoader = newDataLoader(keysAsValues());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've swapped this out for idLoader (and for the next test) purely since I think this valuable enough to test for each batch function.

@@ -665,14 +727,19 @@ public void should_work_with_duplicate_keys_when_caching_disabled() throws Execu
assertThat(future1.get(), equalTo("A"));
assertThat(future2.get(), equalTo("B"));
assertThat(future3.get(), equalTo("A"));
assertThat(loadCalls, equalTo(singletonList(asList("A", "B", "A"))));
if (factory instanceof ListDataLoaderFactory) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit iffy on this - wasn't sure if I should split this out into a separate test but it's 95% the same code.

@dondonz dondonz added this to the Next release 3.4.0 milestone May 19, 2024
Copy link
Member

@bbakerman bbakerman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work

@bbakerman bbakerman merged commit 6ede2e6 into graphql-java:master May 20, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants