I'm encountering an issue while testing a React component using React Testing Library. The component involves fetching data using Axios. The tests fail with the following error:
TypeError: Cannot destructure property 'data' of '(intermediate value)' as it is undefined.
11 |
12 | const fetchFollowers = async () => {
> 13 | const { data } = await axios.get("https://randomuser.me/api/?results=5")
| ^
14 | setFollowers(data.results)
15 | }
16 |
at fetchFollowers (src/components/FollowersList/FollowersList.js:13:21)
Before I show the Test Suites, I just followed the tutorial of this git repository u can easily clone.
https://github.com/harblaith7/React-Testing-Library-Net-Ninja
So my Test Suite looks like this:
FollowerList.test.js:
import { render, screen, fireEvent } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import FollowersList from "../FollowersList";
const MockFollowersList = () => {
return (
<BrowserRouter>
<FollowersList />
</BrowserRouter>
)
}
describe("FollowersList", () => {
beforeEach(() => {
// console.log("RUNS BEFORE EACH TEST")
jest.mock("../../../__mocks__/axios")
})
// beforeAll(() => {
// console.log("RUNS ONCE BEFORE ALL TESTS")
// })
// afterEach(() => {
// console.log("RUNS AFTER EACH TEST")
// })
// afterAll(() => {
// console.log("RUNS ONCE AFTER ALL TESTS")
// })
it('should fetch and render input element', async () => {
render(
<MockFollowersList />
);
const followerDivElement = await screen.findByTestId(`follower-item-0`)
expect(followerDivElement).toBeInTheDocument();
});
it('should fetch and render input element2', async () => {
render(
<MockFollowersList />
);
const followerDivElement = await screen.findByTestId(`follower-item-0`)
expect(followerDivElement).toBeInTheDocument();
});
})
axios.js in mocks:
const mockResponse = {
data: {
results: [
{
name: {
first: "Laith",
last: "Harb"
},
picture: {
large: "https://randomuser.me/api/portraits/men/59.jpg"
},
login: {
username: "ThePhonyGOAT"
}
}
]
}
}
export default {
get: jest.fn().mockResolvedValue(mockResponse)
}
I'm working behind a proxy, but I don't think this is the problem here. Would be grateful for advice!
Greetings
The mocked version of axios in __mocks__/axios.js
is being read but the problem is that react-scripts is adding the jest configuration resetMocks: true
when runing the tests.
This effectively resets all your mock implementations, removing all your fake implementations prior to executing tests.
You can override this configuration in package.json
:
"jest": {
"resetMocks": false
}
Another solution, if you don't want to change this configuration, would be to mock the implementation in your test:
import axios from 'axios';
[...]
it('should fetch and render input element', async () => {
axios.get = jest.fn().mockResolvedValue(<your_mock_response>);
render(
<MockFollowersList />
);
const followerDivElement = await screen.findByTestId(`follower-item-0`)
expect(followerDivElement).toBeInTheDocument();
});
Since this mock is executed after the reset performed by the jest configuration, it allows you to add the fake implementation.