act和useState的单元测试错误,在useEffect中进行API调用



我有一个react功能组件,在该组件中,在应用程序的加载中,我正在抽API调用,该调用已封装在useEffect中,当接收到数据时,我正在更新useState变量。在使用jest和react测试库为以下组件编写单元测试用例时,我收到了act错误和useState变量错误。代码:

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;

测试:

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();
});
});

错误:警告:测试中对Dashboard的更新未封装在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 |结果。真的吗?setSearchInput(result.feats[0](:setSearchInput;|^

此警告表示在组件被拆除后(通过useState(对其进行了更新。你可以在这里阅读Kent C.Dods的完整解释:https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning/.

我会尝试使用这种语法来消除警告:

await act(() => {
expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith(`https://www.themealdb.com/api/json/v1/1/random.php`);
});

最新更新