Join us from October 8-10 in New York City to learn the latest tips, trends, and news about GraphQL federation and API platform engineering.Join us for GraphQL Summit 2024 in NYC
Docs
Start for Free

Testing with Apollo Federation

Unit, integration, end-to-end, composition, and component and operation testing

clientserverfederationtesting

💡 TIP

If you're an enterprise customer looking for more material on this topic, try the Enterprise best practices: Testing course on .

Not an enterprise customer? Learn about GraphOS for Enterprise.

Testing in may seem like it can involve more steps, but that is because your GraphQL architecture can involve many areas of your tech stack, from your frontend with to a backend with , or your infrastructure with your to the individual in your . In practice, all these areas should be properly tested the same way if we were using any other API technology, but often the testing across boundaries like teams or applications can involve some new steps. By the end of this guide you should have:

Unit testing

We recommend creating unit tests for each of your . Resolvers are the code that gets called for each type or in your schema, which creates a natural boundary to test in isolation. When doing so, we recommend mocking as much data as possible using a package like @faker-js/faker. This package generates realistic fake data for mocking inputs and outputs.

Using @faker-js/faker to mock a return value in jest looks something like the following:

import { faker } from "@faker-js/faker";
const testUser = {
userId: faker.datatype.uuid(),
username: faker.internet.userName(),
email: faker.internet.email(),
avatar: faker.image.avatar(),
password: faker.internet.password(),
birthdate: faker.date.birthdate(),
registeredAt: faker.date.past(),
};
const mockedFunction = jest.fn().mockReturnValue(testUser);

Reference resolvers in unit tests

The __resolveReference function (also known as a reference resolver) enables different subgraphs to resolve the of a federated . They are also just functions, making them a good boundary to unit test with mocks. Reference resolvers are vital to the successful execution of federated , so they are important to validate.

Integration testing

Integration tests for subgraphs should start up a single subgraph and send operations to the schema in a mocked or test environment. To test just the subgraph in isolation, validate all the fields giving special focus to the top-level fields in your queries and , and use all permutations of your inputs to check your schema matches your resolvers.

Entity resolvers in integration tests

Depending on your schema and operations, the resulting query plan may fetch data from a subgraph using the entity resolvers. The integration tests in this situation involves mimicking the gateway/. You can execute a query against _entities to do integration tests and your test cases should cover all the entity types that can be resolved by the individual subgraph (all the types marked with @key).

This looks like the following:

query GetEntities($representations: [_Any!]!) {
_entities(representations: $representations) {
... on User {
firstName
}
}
}

with the following input

{
"representations": [
{
"__typename": "User",
"id": "5"
}
]
}

To see more examples on how to test these operations, see Query._entities.

End-to-end testing

Follow these best practices when creating end-to-end tests for your supergraph:

  • Run all your subgraphs and router in a test environment with either mocked or test data
  • Use example operations that are actually executed against your supergraph.
    • You can view the details of recent operations in .
    • Avoid boilerplate or randomly generated operations, because these don't reflect actual traffic.
    • If you are not in production yet, we suggest making these tests as close to what you think they will be as possible.
    • Make sure to include that span multiple subgraphs to validate entity s
  • Use to ensure high operation cardinality.
    • If your test operations don't use any GraphQL variables (or if you use the same variable values across executions), your supergraph is likely to return cached data. This circumvents large portions of execution logic, limiting test effectiveness.
    • By using a variety of operations and values, you help make sure that your tests result in minimal cache hits.

Composition testing

testing is specific to a federated architecture. It involves testing that your successfully compose into a supergraph schema that can resolve the operations sent by clients. You perform these tests with the Rover CLI, via the rover subgraph check command. We recommend performing this check in your CI pipeline as part of code-reviews and in your CD pipeline to confirm the changes you are about to deploy are still valid since the last time you ran the check.

Component and operation testing

Fortunately, clients are not actually aware of when they are using a Federated GraphQL API versus a non-Federated one so the testing best practices remain the same. Our schema can provide a convenient layer to mock our data fetching, or for individual components you can mock the specific client providers that inject or fetch your GraphQL data:

Next
Home
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company