Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions docs/source/development-testing/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,70 @@
});
```

## Testing with Suspense

Check notice on line 259 in docs/source/development-testing/testing.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/development-testing/testing.mdx#L259

**Structural Elements**: Headings should use sentence case. 'Suspense' is a React feature but generally treated as a common noun in this context unless referring to the specific component <Suspense />. ```suggestion ## Testing with suspense ```

When testing components that use `useSuspenseQuery` or other [suspense hooks](../data/suspense/), wrap your React Testing Library `render` call in `await act()`.

Unlike `useQuery`, which keeps the component mounted in a loading state while the request is in flight, `useSuspenseQuery` suspends the component immediately. Without `await act()`, the component stays suspended in your test environment and the test times out.

Check notice on line 263 in docs/source/development-testing/testing.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/development-testing/testing.mdx#L263

**Framing Apollo Products**: Focus on the advantages of the suspense approach rather than the limitations of useQuery. **Language**: The idiom 'in flight' may be difficult for non-native speakers to understand. Use 'active' or 'processing' instead. ```suggestion `useSuspenseQuery` suspends the component immediately, allowing you to manage loading states at the boundary level. Without `await act()`, the component stays suspended in your test environment and the test times out. ```

For example, given this `Greeting` component that uses `useSuspenseQuery`:

```jsx title="greeting.jsx"
import { Suspense } from "react";
import { gql } from "@apollo/client";
import { useSuspenseQuery } from "@apollo/client/react";

export const GET_GREETING_QUERY = gql`
query GetGreeting {
greeting {
message
}
}
`;

export function Greeting() {
const { data } = useSuspenseQuery(GET_GREETING_QUERY);
return <div>{data.greeting.message}</div>;
}
```

Test it by wrapping `render` in `await act()`:

```jsx title="greeting.test.jsx"
import "@testing-library/jest-dom";
import { Suspense } from "react";
import { act, render, screen } from "@testing-library/react";
import { MockedProvider } from "@apollo/client/testing/react";
import { GET_GREETING_QUERY, Greeting } from "./greeting";

const mocks = [
{
request: { query: GET_GREETING_QUERY },
result: {
data: {
greeting: { __typename: "Greeting", message: "Hello" },
},
},
},
];

it("should render the greeting", async () => {
await act(() =>
render(
<MockedProvider mocks={mocks}>
<Suspense fallback={<div>Loading...</div>}>
<Greeting />
</Suspense>
</MockedProvider>
)
);

expect(await screen.findByText("Hello")).toBeInTheDocument();
});
```

The `await act()` wrapper allows React to process the suspended component and deliver the mock response before assertions run.

## Testing error states

Your component's error states are just as important to test as its success state, if not more so. You can use the `MockedProvider` component to simulate both network errors and GraphQL errors.
Expand Down
Loading