У меня есть следующий компонент, который загружает данные из внешнего API с помощью крюка useEffect
при монтировании:
import React, { useEffect, useState } from "react";
import Dropdown from "./common/Dropdown";
import { getWeapons } from "../services/gear";
import { DropdownOptionType } from "./common/Dropdown";
const EMPTY_OPTION = {
key: "0",
label: "",
value: "null"
};
const Gear = () => {
const [weaponOptions, setWeaponOptions] = useState([EMPTY_OPTION]);
const [weapon, setWeapon] = useState("null");
useEffect(() => {
const fetchWeaponsOptions = async (): Promise<void> => {
const weaponsData = await getWeapons();
const newWeaponOptions: DropdownOptionType[] = [
EMPTY_OPTION,
...weaponsData.map(({ id, name }) => {
return {
key: id,
label: name,
value: id
};
})
];
setWeaponOptions(newWeaponOptions);
};
fetchWeaponsOptions();
}, []);
// TODO add weapon dropdown on change, selected weapon state
const handleWeaponChange = ({ value }: DropdownOptionType): void => {
setWeapon(value);
};
return (
<div>
<h2>Gear:</h2>
<Dropdown
defaultValue={weapon}
label="Weapon"
name="weapon"
options={weaponOptions}
onChange={handleWeaponChange}
/>
</div>
);
};
export default Gear;
Я монтирую этот компонент внутри моего компонента приложения:
import React from "react";
import Stats from "./components/Stats";
import Gear from "./components/Gear";
const App = () => {
return (
<div className="App">
<h1>Untitled combat game character creator</h1>
<Stats />
<Gear />
</div>
);
};
export default App;
У меня есть следующий тест для моего компонента приложения:
import React from "react";
import { render } from "@testing-library/react";
import App from "./App";
test("renders app title", () => {
const { getByText } = render(<App />);
const titleElement = getByText(/Untitled combat game character creator/i);
expect(titleElement).toBeInTheDocument();
});
Тест проходит, но выдает следующее предупреждение:
PASS src / App.test.tsx ● Консоль
console.error node_modules/react-dom/cjs/react-dom.development.js:530
Warning: An update to Gear 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 */
This ensures that you're testing the behavior the user would see in the browser. Learn more at ...
in Gear (at App.tsx:11)
in div (at App.tsx:8)
in App (at App.test.tsx:6)
Я попытался обернуть тестовый код в обратный вызов действия, но получаю то же предупреждение:
test("renders app title", () => {
act(() => {
const { getByText } = render(<App />);
const titleElement = getByText(/Untitled combat game character creator/i);
expect(titleElement).toBeInTheDocument();
});
});
И:
test("renders app title", () => {
let titleElement;
act(() => {
const { getByText } = render(<App />);
titleElement = getByText(/Untitled combat game character creator/i);
});
expect(titleElement).toBeInTheDocument();
});
Но я получаю одно и то же предупреждение в обоих случаях. Каков будет правильный способ справиться с этим?