UNPKG

use-async-resource

Version:

A custom React hook for simple data fetching with React Suspense

70 lines (54 loc) 2.4 kB
import { act, renderHook } from '@testing-library/react-hooks'; import { updateCache } from './updateCache'; import { useAsyncResource } from './useAsyncResource'; import { resourceCache } from './cache'; import { suspendFor } from './test.helpers'; describe('updateCache', () => { const apiFn = (id: number) => id < 10 ? Promise.resolve({ id, name: 'test name' }) : Promise.reject({ message: 'error' }); afterEach(() => { resourceCache(apiFn).clear(); }); it('should transition a data reader without throwing in between', async () => { // get the data reader from the custom hook, with params const { result } = renderHook(() => useAsyncResource(apiFn, 1)); const [dataReader, updateDataReader] = result.current; // wait for it to fulfill await suspendFor(dataReader); // should be able to get raw data from the data reader expect(dataReader()).toStrictEqual({ id: 1, name: 'test name' }); // update the data reader with a transition const updater = updateCache(apiFn, 2) .then(() => { act(() => updateDataReader(2)); }); // while update is in progress, data reader should remain the same const [prevDataReader] = result.current; expect(prevDataReader).toStrictEqual(dataReader); // wait for the update to happen await updater; // the new data reader should be available immediately const [newDataReader] = result.current; expect(newDataReader).not.toStrictEqual(prevDataReader); expect(newDataReader()).toStrictEqual({ id: 2, name: 'test name' }); }); it('should throw a failure if update was not successful', async () => { // get the data reader from the custom hook, with params const { result } = renderHook(() => useAsyncResource(apiFn, 1)); const [dataReader, updateDataReader] = result.current; // wait for it to fulfill await suspendFor(dataReader); // should be able to get raw data from the data reader expect(dataReader()).toStrictEqual({ id: 1, name: 'test name' }); // update the data reader with a transition, but expect a failure to happen await updateCache(apiFn, 10) .then(() => { act(() => updateDataReader(10)); }); // verify that the new data reader fails with an error const [newDataReader] = result.current; expect(newDataReader).toThrowError(Error('error')); }); });