Как проверить useEffect с асинхронной функцией и setState внутри - PullRequest
4 голосов
/ 02 июня 2019

Я настроил проект github, чтобы понять, как лучше тестировать реакцию (v 16.8.0) useEffect hook.Я делаю вызов API для извлечения данных внутри useEffect и задаю полученные данные как элемент компонента состояния.Мой компонент получает запрос как реквизит и выполняет вызов API, если строка реквизита запроса не пуста.Я хотел бы проверить, что с помощью непустого запроса выполняется вызов API и компонент устанавливает правильное состояние.

Я знаю, что проблема, с которой приходится сталкиваться при тестировании useEffect , заключается в том, чтоэффекты, связанные с useEffect , не блокируют браузер от обновления экрана, поэтому тесты заканчиваются до того, как useEffect выполнит свою работу.Я прочитал из документации React, что существует API из act-test-utils , называемый act , который, как предполагается, оборачивает код, визуализирующий компонент и выполняющий обновления для него.Даже если я попытался использовать его, у меня все еще были те же проблемы с моим кодом.

Это компонент, который я пытаюсь проверить:

const DisplayData = ({ query, onQueryChange }) => {
    const [data, setData] = useState({ hits: [] });

    useEffect(() => {
        const fetchData = async () => {
            const result = await axios.get(
                `http://hn.algolia.com/api/v1/search?query=${query}`,
            );
            setData(result.data);
        };
        if (!!query) fetchData();
    }, [query]);

    return (
        <ul>
            {data.hits.map(item => (
                <li key={item.objectID}>
                    <a href={item.url}>{item.title}</a>
                </li>
            ))}
        </ul>
    );
};

, и это тест, который я написалдля этого:

it("should show new entries when query is set", () => {
    const el = document.createElement("div");
    document.body.appendChild(el);
    axios.get.mockResolvedValue({ data: { hits: FAKE_HITS } });
    act(() => {
        render(<DisplayData query='pippo' />, el);
    });
    const liCounts = el.querySelectorAll("li");
    expect(liCounts.length).toBe(2);
});

Я продолжаю получать предупреждение о том, что Обновление DisplayData внутри теста не было включено в действие (...) , и мой тест не прошел, потому что liCounts получено is_0_ вместо ожидаемого 2 .

Вставляя те же консольные сообщения для отладки приложения, я полагаю, что проблема в том, что useEffect запускается после выполнения теста, но я больше не знаю, как действовать.

ОБНОВЛЕНИЕ Благодаря @jonrsharpe я решил свою проблему с помощью React версии 16.9.0-alpha.0, котораяимеет асинхронную версию act api.

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