response-dom - Обновление до ... внутри теста не было включено в действие (...) - PullRequest
0 голосов
/ 01 февраля 2020

У меня есть следующий компонент, который загружает данные из внешнего 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();
});

Но я получаю одно и то же предупреждение в обоих случаях. Каков будет правильный способ справиться с этим?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...