So basically I'm trying to use a mock that I made with fake data for test some components. It was all fine but when I was trying to make use of the "findAllByRole" method it just return me an empty object and throws me an error telling me that all the items with the role "listitem" don't exist.
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import MainSection from './MainSection.js';
import { getItems } from '../../Database/Database.js';
import axios from 'axios';
import mockProducts from '../../Database/mockProducts.js';
jest.mock('axios');
beforeEach(() => {
render(<MainSection />);
});
test('Check if renders all the 20 items in the MainSection', async () => {
axios.get.mockResolvedValue({
data: mockProducts,
});
await getItems();
const allBoxes = screen.findAllByRole('listitem');
expect(allBoxes).toHaveLength(20);
});
import React, { useState, useEffect } from 'react';
import SearchBar from './SearchBar/SearchBar.js';
import FiltersBox from './FiltersBox/FiltersBox.js';
import { getItems } from '../../Database/Database.js';
import './MainSection.css';
function MainSection() {
const [items, setItems] = useState([]);
useEffect(() => {
getItems().then(res => setItems(res));
}, []);
return (
<section>
<article className='items_container-main'>
<div className='items_container' role='list'>
items.map(item => (
<div
className='item_box'
style={{ backgroundImage: `url(${item.image})` }}
key={item.id}
role='listitem'>
<div className='item_box-data_container'>
<div className='item_box-data_container-price_star'>
<div className='item_box-price'>${item.price}</div>
<div className='item_box-title'>{item.title}</div>
</div>
</div>
))}
</div>
</article>
</section>
);
}
export default MainSection;
import axios from 'axios';
export async function getItems() {
try {
const { data } = await axios.get('https://fakestoreapi.com/products');
return data;
} catch (error) {
console.log('Error! D:', error);
}
}
I think that's the reason of that error, because I need to make the test use that mock with fake data as an API response data, but I don't know how can I do it...
axios
module using jest.mock('axios')
, you can just mock axios.get()
method.axios.get()
.await screen.findAllByRole('listitem')
to waiting for appearanceMainSection.jsx
:
import React, { useState, useEffect } from 'react';
import { getItems } from './Database';
function MainSection() {
const [items, setItems] = useState([]);
console.log("🚀 ~ file: MainSection.jsx:6 ~ MainSection ~ items:", items)
useEffect(() => {
getItems().then((res) => setItems(res));
}, []);
return (
<section>
<article className="items_container-main">
<div className="items_container" role="list">
{items.map((item) => {
return <div key={item.id} role='listitem'>{item.title}</div>;
})}
</div>
</article>
</section>
);
}
export default MainSection;
MainSection.test.jsx
:
import React from 'react';
import { render, screen } from '@testing-library/react';
import MainSection from './MainSection';
import axios from 'axios';
test('Check if renders all the 20 items in the MainSection', async () => {
const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValue({
data: [
{ id: 1, title: 'a' },
{ id: 2, title: 'b' },
],
});
render(<MainSection />);
const allBoxes = await screen.findAllByRole('listitem');
expect(allBoxes).toHaveLength(2);
axiosGetSpy.mockRestore();
});
Test result:
PASS stackoverflow/75539392/MainSection.test.jsx (9.547 s)
✓ Check if renders all the 20 items in the MainSection (96 ms)
console.log
🚀 ~ file: MainSection.jsx:6 ~ MainSection ~ items: []
at MainSection (stackoverflow/75539392/MainSection.jsx:6:11)
console.log
🚀 ~ file: MainSection.jsx:6 ~ MainSection ~ items: [ { id: 1, title: 'a' }, { id: 2, title: 'b' } ]
at MainSection (stackoverflow/75539392/MainSection.jsx:6:11)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.348 s, estimated 12 s