如何用Jest模拟axios-hooks的useAxios钩子?(报TypeError错误)
The error you're seeing comes from a mismatch between what your mock returns and what the useAxios hook actually provides. Let's break down the fix step by step:
Key Issue: Incorrect Mock Return Value
useAxios is a React hook that synchronously returns an array (not a promise) containing an object with data, loading, and error properties. Your current mock returns a promise, which breaks the destructuring in your component (const [{ data: projects, loading, error }] = useAxios(...)).
Corrected Test Code
Here's the updated test with the proper mock setup, plus additional tests for loading and error states to cover all component paths:
import React from 'react' import { render, cleanup } from '@testing-library/react' import Projects from '../Projects' import useAxios from 'axios-hooks' jest.mock('axios-hooks') // Mocks the entire axios-hooks module describe('Projects component', () => { afterEach(cleanup) it('renders the project table with mock data', () => { const fakeProjects = [ { title: 'Testing Project Alpha', startDate: '2020-04-18', description: 'This is just for testing', team: 'A, B, C' }, { title: 'Testing Project Beta', startDate: '2020-04-19', description: 'This is just for testing too', team: 'X, Y, Z' } ] // Mock useAxios to return the expected array structure useAxios.mockReturnValue([{ data: fakeProjects, loading: false, error: null }]) const { getByTestId, getByText } = render(<Projects />) // Verify the table exists expect(getByTestId('project-table-id')).toBeInTheDocument() // Optional: Verify mock data is rendered expect(getByText('Testing Project Alpha')).toBeInTheDocument() expect(getByText('Testing Project Beta')).toBeInTheDocument() }) it('displays loading message when data is fetching', () => { useAxios.mockReturnValue([{ data: null, loading: true, error: null }]) const { getByText } = render(<Projects />) expect(getByText('Loading...')).toBeInTheDocument() }) it('displays error message when fetch fails', () => { useAxios.mockReturnValue([{ data: null, loading: false, error: new Error('API Error') }]) const { getByText } = render(<Projects />) expect(getByText('Error!')).toBeInTheDocument() }) })
Explanation of Changes:
- Mock Return Value: Instead of returning a promise, we use
mockReturnValueto return an array matching the structureuseAxiosprovides. The first element of the array is an object withdata,loading, anderrorproperties. - Removed Unnecessary Async: Since we're mocking the hook to return data synchronously, there's no need for
async/awaitin the test. - Added State Coverage: We now test all three states (loaded, loading, error) to ensure the component behaves correctly in each scenario.
Why This Works:
When your component calls useAxios, it gets the mock array instead of making a real API call. The destructuring works as expected because the mock returns the exact structure the component expects.
内容的提问来源于stack exchange,提问作者lmiguelvargasf

