I have a react functional component where onload of the App I am smoking an API call which I have wrapped in useEffect and when the data is received I am updating the useState variable. While writing a unit test case for the below component using jest and react testing library I am receiving act error and useState variable error. Code:
import React, { useState, useEffect } from "react";
import TextField from "@material-ui/core/TextField";
import Media from "./card";
import Alert from "@material-ui/lab/Alert";
import fetchData from "../API";
const Dashboard = () => {
const [searchInput, setSearchInput] = useState(null);
const [receipeNotFound, setReceipeNotFound] = useState(false);
useEffect(() => {
fetchData(
`https://www.themealdb.com/api/json/v1/1/random.php`,
randomReceipe
);
}, []);
const randomReceipe = (result) => {
result.meals ? setSearchInput(result.meals[0]) : setSearchInput(null);
};
const searchData = (value) => {
if (value) {
setSearchInput(null);
setReceipeNotFound(false);
fetchData(
`https://www.themealdb.com/api/json/v1/1/search.php?s=${value}`,
searchRecepie
);
} else {
setSearchInput(null);
}
};
const notFound = (status) => {
setReceipeNotFound(status);
setSearchInput(null);
};
const searchRecepie = (result) => {
result.meals ? setSearchInput(result.meals[0]) : notFound(true);
};
return (
<div>
<TextField
data-testid="searchInput"
id="standard-basic"
label="Search"
onBlur={(event) => searchData(event.currentTarget.value)}
/>
{receipeNotFound ? (
<Alert data-testid="alert" severity="error">
Receipe not found!
</Alert>
) : null}
{Boolean(searchInput) ? (
<Media data-testid="mediaLoading" loading={false} data={searchInput} />
) : (
<Media data-testid="Media" loading={true} data={{}} />
)}
</div>
);
};
export default Dashboard;
Test:
import React from "react";
import Dashboard from "./dashboard";
import ReactDOM from "react-dom";
import {
render,
screen,
act,
waitFor,
fireEvent,
} from "@testing-library/react";
import { randomMockWithOutVideo, randomMockWithVideo } from "./API.mock";
global.fetch = jest.fn();
let container;
describe("Card ", () => {
test("Should renders data when API request is called with meals data", async (done) => {
jest.spyOn(global, "fetch").mockResolvedValue({
json: jest.fn().mockResolvedValue({ meals: [randomMockWithVideo] }),
});
const { getByTestId, container } = render(<Dashboard />);
expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith(
`https://www.themealdb.com/api/json/v1/1/random.php`
);
});
afterEach(() => {
jest.restoreAllMocks();
});
});
error: Warning: An update to Dashboard inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
19 | result.meals ? setSearchInput(result.meals[0]) : setSearchInput(null); | ^