I have a custom hook (useFetch
), which I’m using inside a page to pass data into a <Products/>
component.
export default function App() {
const { products, totalProducts, currentPage, handleNextPage } = useFetch();
....
<div>{products && <Products products={products}/> }</div>
The problem arrives when I try to use this hook inside a test file to test if Products are being rendered.
This is my custom hook:
import React, { useState, useEffect } from "react";
const useFetch = () => {
const [products, setProducts] = useState([]);
const [totalProducts, setTotalProducts] = useState(0);
const [currentPage, setCurrentPage] = useState(1);
const limit = 30;
const fetchData = async (start) => {
const res = await fetch(
`https://dummyjson.com/products?skip=${start}&limit=${limit}`,
);
const data = await res.json();
setProducts(data.products);
setTotalProducts(data.total);
};
useEffect(() => {
fetchData((currentPage - 1) * limit);
}, [currentPage]);
const handleNextPage = (page) => {
setCurrentPage(page);
};
return {
products,
totalProducts,
handleNextPage,
currentPage,
};
};
export { useFetch };
And this is my test file, which I’m currently only trying to get the populated array of data, but I’m always getting an empty array:
import { renderHook } from "@testing-library/react";
import Products from "./Products";
import { expect } from "vitest";
import { useFetch } from "../../hooks/useFetch";
describe("Products component", () => {
test("render 30 first products correctly", () => {
const { result } = renderHook(() => useFetch());
if (result.current.products) {
expect(result.current.products.length).toBe(30);
}
});
});
What should I do to implement this custom hook? Should I mock it somehow?
I tried to use waitFor
method in this way, but still not getting the fetched result data :
await waitFor(() => {
// expect(screen.getByText("ID")).toBeInTheDocument();
// });
2
Answers
you don’t want to make HTTP requests within your tests. instead, you should mock the response from your custom hook. something like this could work:
You can mock the file itself:
Most likely you have to replace
'hooks/useFetch.tsx'
with your hook’s relative path.There is also a way to use
msw
andserver.use()
to mock a request from a certain URL itself.