Как устранить предупреждение «обновление не было включено в act ()» в тестирующей библиотеке реагирующей? - PullRequest
1 голос
/ 07 февраля 2020

Я работаю с простым компонентом, который дает побочный эффект. Мой тест пройден, но я получаю предупреждение Warning: An update to Hello inside a test was not wrapped in act(...)..

Я также не знаю, является ли waitForElement лучшим способом написать этот тест.

Мой компонент

export default function Hello() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      setPosts(response.data);
    }

    fetchData();
  }, []);

  return (
    <div>
      <ul>
        {
          posts.map(
            post => <li key={post.id}>{post.title}</li>
          )
        }
      </ul>
    </div>
  )
}

Мой компонентный тест

import React from 'react';
import {render, cleanup, act } from '@testing-library/react';
import mockAxios from 'axios';
import Hello from '.';

afterEach(cleanup);

it('renders hello correctly', async () => {
  mockAxios.get.mockResolvedValue({
    data: [
        { id: 1, title: 'post one' },
        { id: 2, title: 'post two' },
      ],
  });

  const { asFragment } = await waitForElement(() => render(<Hello />));

  expect(asFragment()).toMatchSnapshot();
});

1 Ответ

0 голосов
/ 11 февраля 2020

Использование waitForElement - правильный путь из документов:

Дождитесь, пока смоделированное обещание запроса get разрешится, и компонент вызовет setState и повторно выполнит рендеринг. waitForElement ждет, пока обратный вызов не выдаст ошибку

Вот рабочий пример для вашего случая:

index.jsx:

import React, { useState, useEffect } from 'react';
import axios from 'axios';

export default function Hello() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
      setPosts(response.data);
    };

    fetchData();
  }, []);

  return (
    <div>
      <ul data-testid="list">
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

index.test.jsx:

import React from 'react';
import { render, cleanup, waitForElement } from '@testing-library/react';
import axios from 'axios';
import Hello from '.';

jest.mock('axios');

afterEach(cleanup);

it('renders hello correctly', async () => {
  axios.get.mockResolvedValue({
    data: [
      { id: 1, title: 'post one' },
      { id: 2, title: 'post two' },
    ],
  });
  const { getByTestId, asFragment } = render(<Hello />);

  const listNode = await waitForElement(() => getByTestId('list'));
  expect(listNode.children).toHaveLength(2);
  expect(asFragment()).toMatchSnapshot();
});

Результаты модульных испытаний со 100% покрытием:

 PASS  stackoverflow/60115885/index.test.jsx
  ✓ renders hello correctly (49ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 index.jsx |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        4.98s

index.test.jsx.snapshot:

// Jest Snapshot v1

exports[`renders hello correctly 1`] = `
<DocumentFragment>
  <div>
    <ul
      data-testid="list"
    >
      <li>
        post one
      </li>
      <li>
        post two
      </li>
    </ul>
  </div>
</DocumentFragment>
`;

исходный код: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60115885

...