I'm currently trying to test a components that uses data provived by a custom hook and check if it renders all the elements in it.
AgentsContainer.js
import React from 'react';
import { useFetch } from '../../hooks/useFetch.js';
import AgentBox from './AgentBox/AgentBox.js';
function AgentsContainer() {
const { agents, loading, error } = useFetch(
'https://valorant-api.com/v1/agents'
);
return (
<section>
<div>
{error && <div>Error: {error.message}</div>}
{loading && <div>Loading...</div>}
{agents?.map(agent => {
return (
agent.isPlayableCharacter && (
<AgentBox key={agent.uuid} data-testid='agent-card' {...agent} />
)
);
})}
</div>
</section>
);
}
export default AgentsContainer;
Also, notice that if I delete the question mark that is after the "agents" variable, it returns me an error saying "TypeError: Cannot read properties of undefined (reading 'map')".
useFetch.js
import { useState, useEffect } from 'react';
import axios from 'axios';
export function useFetch(url) {
const [agents, setAgents] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState();
useEffect(() => {
setLoading(true);
axios
.get(url)
.then(({ data: { data } }) => {
setAgents(data);
})
.catch(error => setError(error))
.finally(() => setLoading(false));
}, []);
return { agents, loading, error };
}
AgentsContainer.test.js
import React from 'react';
import { render, screen } from '@testing-library/react';
import AgentsContainer from './AgentsContainer.js';
import agentsMock from '../../mock/mock.js';
import axios from 'axios';
jest.mock('axios');
test('Renders Agents cards', async () => {
axios.get.mockResolvedValue({
data: agentsMock,
loading: true,
error: 'Something went wrong D:'
});
render(<AgentsContainer />);
const agentsCards = await screen.findAllByTestId('agent-card');
expect(agentsCards).toHaveLength(3);
});
Console
Unable to find an element by: [data-testid="agent-card"]
Ignored nodes: comments, script, style
<body>
<div>
<section>
<div />
</section>
</div>
</body>
16 | render(<AgentsContainer />);
17 |
> 18 | const agentsCards = await screen.findAllByTestId('agent-card');
| ^
19 |
20 | expect(agentsCards).toHaveLength(3);
21 | });
The "mockAgents" that I was importing in the test file, is just an array of object, it has inside only 3 objects with multiple data inside, I don't put the mock here because it has so much data. But if you really need it, then just let me know, please :)
Ok I found the problem.
I just changed the way I was mocking the JSON file and this solved the problem.
AgentsContainer.test.js
test('Should render Agents cards', async () => {
axios.get.mockResolvedValue({
data: { data: agentsMock }, // Here was the problem.
loading: true,
error: 'Something went wrong D:'
});
render(<AgentsContainer />);
const agentsCards = await screen.findAllByTestId('agent-card');
expect(agentsCards).toHaveLength(3);
});