use-swr-immutable.test.tsx
Overview
This file contains a suite of automated tests for verifying the behavior of the SWR React data fetching hook, specifically focusing on the immutable mode and related configurations. It leverages @testing-library/react for rendering and user interaction simulation, and tests different scenarios on how useSWR, useSWRImmutable, and the immutable middleware behave with respect to revalidation and caching.
The tests ensure that:
Data is revalidated correctly on component mounting.
The
revalidateIfStaleoption correctly toggles revalidation behavior.The
useSWRImmutablehook prevents unnecessary revalidation.The
immutablemiddleware works equivalently touseSWRImmutable.Changes in keys with
revalidateIfStaledisabled trigger expected fetcher calls.
These tests help guarantee that the SWR caching and revalidation logic behaves as expected when using immutable data fetching strategies.
Detailed Explanation
Imports and Utilities
screen,act, andfireEventfrom@testing-library/reactare used for DOM querying, async handling, and event simulation.useState from React for component state.
useSWRanduseSWRImmutablefrom swr package for data fetching hooks.immutablemiddleware from swr/immutable to make SWR behave immutably.Utility functions imported from
./utils:sleep: async delay function.createKey: generates unique keys for SWR caching.nextTick (aliased as
waitForNextTick): waits for the next event loop tick.focusOn: used to simulate window focus events.renderWithConfig: renders components with necessary SWR configuration.
Test Suite: useSWR - immutable
This describe block groups tests regarding useSWR hooks' behavior with immutable options and middleware.
Test Cases
1. should revalidate on mount
Purpose: Verify that when a component using
useSWRmounts, the data is revalidated (fetcher is called again).Implementation:
useDatahook callsuseSWRwith a key and a fetcher that increments a sharedvalue.Pagecomponent shows current data and a button to mount a childComponentwhich also uses the sameuseDatahook.After mounting
Componentby button click, data should increment due to revalidation.
Key Points:
dedupingIntervalis set to0to disable deduplication delay.Uses
findByTextto await updated UI.
Example Usage:
const useData = () => useSWR(key, () => value++, { dedupingInterval: 0 });
2. should not revalidate on mount when revalidateIfStale is enabled
Purpose: Verify that when
revalidateIfStaleis set tofalse, mounting a component does not trigger revalidation.Implementation:
Similar setup to the first test but with
revalidateIfStale: false.After mounting the child component, data should remain unchanged.
Important Notes: This tests the option that disables automatic revalidation on mount for stale data.
3. should not revalidate with the immutable hook
Purpose: Confirm that
useSWRImmutablehook disables revalidation on mount and on focus.Implementation:
useSWRImmutableused instead ofuseSWR.After mounting child component and simulating window focus, data remains unchanged.
Significance:
useSWRImmutableis a specialized hook for truly immutable data that should not refresh automatically.
4. should not revalidate with the immutable middleware
Purpose: Ensure that using the
immutablemiddleware withuseSWRdisables revalidation.Implementation:
useSWRwithuse: [immutable]option.Similar checks as previous test, data does not refresh on mount or focus.
Comparison: This middleware approach achieves the same effect as
useSWRImmutable.
5. should not revalidate with revalidateIfStale disabled when key changes
Purpose: Test that when
revalidateIfStaleis false, changing keys triggers fetcher calls only once per key.Implementation:
Defines a fetcher mock function.
Toggles between two keys by updating state.
Asserts that fetcher is called exactly twice — once per unique key.
Important Detail: This test validates that stale data is not revalidated unnecessarily even when keys change, respecting deduplication.
Important Implementation Details
Deduplication Interval: All tests set
dedupingInterval: 0to disable SWR's fetcher call deduplication delay, ensuring fetch calls happen immediately when expected.Revalidation Options:
revalidateIfStalecontrols whether stale cache triggers revalidation on mount and focus.useSWRImmutableand theimmutablemiddleware essentially prevent revalidation, ideal for static or immutable data.
Event Simulation:
fireEvent.clicksimulates user interactions.focusOn(window)simulates window focus to test focus-triggered revalidations.
Async Handling:
await act(() => sleep(x))ensures React state updates and effects are flushed before assertions.await waitForNextTick()ensures promises and microtasks settle.
Interaction with Other Parts of the System
Utilities (
./utils): The test file depends on utility helpers for timing, key generation, and rendering configuration tailored for SWR.SWR Library: Tests the behavior of SWR hooks and middleware, which are core to the data fetching strategy in the application.
React Components: Defines minimal test components to simulate real-world usage of hooks in React UI components.
Testing Library: Uses React Testing Library to simulate user interaction and DOM querying.
This file is primarily for validating SWR's caching and revalidation logic, ensuring reliable data consistency and performance optimizations in components that consume asynchronous data.
Visual Diagram
flowchart TD
A[useSWR / useSWRImmutable Hook] -->|calls fetcher| B[Fetcher Function]
A -->|returns| C[Data & State]
C --> D[Component using useData hook]
D --> E[Page Component]
E -->|renders| F[Button to mount Child Component]
F -->|onClick| G[Child Component (also uses useData)]
G -->|mount triggers| H[Revalidation or not depending on config]
subgraph Revalidation Behavior
direction LR
I[revalidateIfStale: true] -->|triggers| H
J[revalidateIfStale: false] -->|no revalidation| H
K[useSWRImmutable / immutable middleware] -->|no revalidation| H
end
H -->|updates| C
C -->|displayed as| L["data: {value}"]
Summary
This test file rigorously verifies the behavior of SWR's immutable data fetching modes and options, ensuring that components correctly avoid unnecessary data revalidation under several configurations. It uses React Testing Library to simulate user interactions and lifecycle events, confirming that the SWR hooks behave as intended for both mutable and immutable data scenarios. The tests ensure data consistency, performance optimization, and expected fetcher call frequencies, which are critical for scalable React applications using SWR.