use-swr-config-callbacks.test.tsx
Overview
This file contains a comprehensive suite of unit tests for verifying the behavior of configuration callbacks in the useSWR React hook. useSWR is a popular data fetching library for React that provides built-in features like caching, revalidation, and request deduplication.
The tests focus on ensuring that various lifecycle callbacks provided via the useSWR configuration options:
onSuccessonErroronErrorRetryonLoadingSlowonDiscarded
are triggered correctly and always use the latest version of the callback when component props or state change.
These tests simulate different data fetching scenarios, including successful responses, errors, retries, slow loading detection, and race conditions with mutations. The file uses React Testing Library to render components, simulate user interactions, and assert on DOM outputs and side effects.
Detailed Description of Tests and Key Functions
Common Utilities Used
createKey() - Generates a unique key for useSWR cache keys.
createResponse(data, options?) - Simulates a fetcher function returning data or throwing errors, with optional delay.
renderWithConfig(component) - Renders React components wrapped with SWR configuration context for testing.
sleep(ms) - Returns a Promise that resolves after
msmilliseconds, useful for simulating delays.
These utilities support simulating asynchronous fetches and SWR behaviors.
Test Cases
1. should trigger the onSuccess event with the latest version of the onSuccess callback
Purpose:
Ensure that when the onSuccess callback is updated via new props, the latest callback is called on every successful fetch/revalidation.
Implementation Details:
A
Pagecomponent usesuseSWRwithonSuccesscallback setting externalstateto the current proptext.The component renders fetched
dataand currenttext, and exposes amutate()method to trigger revalidation.The test:
Renders
<Page text="a" />, asserts initial state and data,Re-renders with without triggering revalidation (state unchanged),
Then triggers
mutate(), ensuringonSuccesssees the updatedtext("b").
Parameters:
props: { text: string }- Text prop that influences the callback behavior.
Return Value:
JSX element showing fetch data and props.
Example Usage:
<Page text="a" />
2. should trigger the onError event with the latest version of the onError callback
Purpose:
Verify that the onError callback reflects the latest prop values on fetch errors.
Implementation Details:
The fetcher always throws an error with incrementing count.
onErrorsets externalstatetoprops.text.The component displays error messages and triggers revalidation on click.
Tests that after prop changes and revalidation,
onErrorcallback uses latest props.
3. should trigger the onErrorRetry event with the latest version of the onErrorRetry callback
Purpose:
Confirm onErrorRetry callback uses the latest props when scheduling retry logic.
Implementation Details:
Fetcher throws errors.
onErrorRetrycapturesprops.textintostateand triggers revalidation.Tests that after props update and automatic retry, the latest callback version is used.
4. should trigger the onLoadingSlow and onSuccess event with the lastest version of the callbacks
Purpose:
Test that onLoadingSlow and onSuccess callbacks trigger with updated props.
Implementation Details:
Fetcher delays response beyond
loadingTimeout.onLoadingSlowfires when loading exceeds timeout.After data resolves,
onSuccessfires.Both callbacks update shared
statewith latestprops.text.
5. should trigger the onDiscarded callback when having a race condition with mutate
Purpose:
Verify that the onDiscarded callback fires when a mutation is discarded due to race conditions.
Implementation Details:
Mutate is called shortly after initial fetch starts.
The first fetch response is discarded because the mutation overrides it.
Test asserts
onDiscardedis called with the correct key.
6. should not trigger the onSuccess callback when discarded
Purpose:
Ensure that onSuccess is not called if the fetch is discarded.
Implementation Details:
Similar to previous test but also tracks successful events.
After mutation causes discard, verifies that
onSuccesscallback is never called.
Important Implementation Details and Algorithms
Latest callback reference:
These tests verify that callbacks passed inuseSWRconfig always run with the latest closure/context values even when props change. This is critical because SWR internally keeps a stable reference to callbacks but must ensure updated closures are called.Simulating async behavior:
The tests usesleepand artificial delays increateResponseto simulate network latency and error conditions, allowing testing of loading slow states and retries.Race condition detection:
TheonDiscardedtests mimic concurrent mutations and fetches to simulate real-world race conditions where stale fetch results are discarded.Revalidation via mutate:
Tests explicitly callmutate()to trigger revalidation and verify callback behavior on fresh fetches.
Interaction with Other System Parts
Depends on
useSWRhook fromswrpackage which provides data fetching and caching.Uses React Testing Library (
@testing-library/react) for rendering and user event simulation.Imports utility helpers (
sleep,createResponse,createKey,renderWithConfig) from sibling./utilsmodule to simulate fetch and render environments.Part of a test suite validating SWR's internal config callback mechanism, ensuring stability and correctness in the broader SWR library.
Visual Diagram
The following flowchart illustrates the main flow and relationships between key functions and tests in this file, focusing on the lifecycle of SWR config callbacks and their triggering conditions.
flowchart TD
A[Start Test] --> B[Render Page component with useSWR]
B --> C{useSWR fetcher returns data or error}
C -->|Success| D[onSuccess callback fired with latest props]
C -->|Error| E[onError callback fired with latest props]
E --> F[onErrorRetry triggers revalidation]
F --> B
B --> G[User triggers mutate()]
G --> B
B --> H{Loading time > loadingTimeout?}
H -->|Yes| I[onLoadingSlow callback fired]
H -->|No| J[Continue normal flow]
B --> K{Race condition detected?}
K -->|Yes| L[onDiscarded callback fired]
K -->|No| J
D --> M[Assertions check callback state]
E --> M
F --> M
I --> M
L --> M
M --> N[End Test]
Summary
This test file validates that useSWR configuration callbacks:
Are always called with the latest prop/state values.
Correctly handle success, error, retry, loading slow, and discard events.
Behave predictably under asynchronous and race condition scenarios.
Support mutation-triggered revalidation and updates.
It provides critical assurance of the SWR hook’s callback lifecycle integrity, ensuring consumers can rely on accurate and up-to-date side-effect handling in their React components.