When you try to call setState
mutate the state. We need to use act() function to
make sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.
Since your fetchData
returns a promise, we need to use async act(...)
, you need React version at least v16.9.0-alpha.0
. For more info about act()
function, see react-act-example.
react-hook-testing-library
re-export act() function from chosen renderer.
Besides, I just use jest.spyOn(axios, 'get').mockResolvedValueOnce()
to mock axios.get()
method without installing any extra package.
Note: I return response.data
, not await response.data.data
.
Now, the working unit test should be:
useFetch.ts
:
import { useState, useCallback } from 'react';
import axios from 'axios';
export const useFetch = () => {
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const fetchData = useCallback(async (url: string) => {
setLoading(true);
try {
const response = await axios.get(url);
const data = response.data;
setLoading(false);
return data;
} catch (error: any) {
if (error.name !== 'AbortError') {
setLoading(false);
setError(error.message);
}
}
}, []);
return { error, loading, fetchData };
};
useFetch.test.ts
:
import { useFetch } from './useFetch';
import axios from 'axios';
import { renderHook, act } from '@testing-library/react-hooks';
describe('useFetch', () => {
it('fetches successfully data from an API', async () => {
const mockData = { data: 'test response' };
const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValueOnce({ data: mockData })
const { result } = renderHook(() => useFetch());
expect(result.current.error).toBe(null);
await act(async () => {
await expect(result.current.fetchData('react')).resolves.toEqual(mockData);
})
axiosGetSpy.mockRestore();
});
});
Test result:
PASS stackoverflow/74063562/useFetch.test.ts (17.219 s)
useFetch
✓ fetches successfully data from an API (16 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 83.33 | 0 | 100 | 81.25 |
useFetch.ts | 83.33 | 0 | 100 | 81.25 | 16-18
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 21.31 s
package versions:
"@testing-library/react-hooks": "^8.0.1",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4