Как я могу дождаться результатов api, прежде чем выполнять тест matchSnapshot?

#javascript #reactjs #jestjs #enzyme #react-testing-library

Вопрос:

У меня есть тест, который сопоставляет моментальный снимок с DOM. Я не уверен, использую ли я для этого правильное монтирование/рендеринг или правильную библиотеку тестирования. Проблема, с которой я сталкиваюсь, заключается в том, что при вызове компонента он ожидает результата API. Тем не менее, мой тест не ждет результата api, даже если я приложил к этому определенные усилия. Интересно, сделал ли я что-то не так или использовал неправильную функцию из библиотеки.

Это то, что я пробовал.

 await act(async () => {
      const { container } = render(<Home />);

      await mockGetMovies;

      expect(container).toMatchInlineSnapshot(`
      <div>
        <main>
          <h1>
            Movies (1)
          </h1>
        </main>
      </div>
    `);
    });
 

Снимок (фактический)

  <p>
    Fetching data...
 </p>
 

когда это должно быть (ожидание)

 <main>
   <h1>
      Movies (1)
   </h1>
</main>
 

Вот как выглядит полный тестовый код:

 import React from 'react';
import { render } from '@testing-library/react';
import { getMovies } from '../app/requests/getMovies';
import Home from '.';
import { act } from 'react-dom/test-utils';

jest.mock('../app/requests/getMovies');

const mockGetMovies = getMovies as jest.Mock;

describe('/', () => {
  beforeEach(() => {
    mockGetMovies.mockResolvedValue([
      {
        Title: 'Titanic',
      },
    ]);
  });

  it('should render the homepage', async () => {
    await act(async () => {
      const { container } = render(<Home />);

      await mockGetMovies;

      expect(container).toMatchInlineSnapshot(`
      <div>
        <main>
          <h1>
            Movies (1)
          </h1>
        </main>
      </div>
    `);
    });
  });
});
 

Вот как выглядит этот компонент

 import React, { useEffect, useState } from 'react';
import { getMovies } from '../app/requests/getMovies';

const Home = () => {
  const [movies, setMovies] = useState([]);
  useEffect(() => {
    getMovies().then((data) => {
      setMovies(data);
    });
  }, []);

  if (movies.length == 0) {
    return <p>Fetching data...</p>;
  }

  return (
    <main>
      <h1>Movies ({movies.length})</h1>
    </main>
  );
};

export default Home;
 

Комментарии:

1. Замените ваши ожидающие mockGetMovies на — await act(() => Promise.resolve());

2. @Shyam, это тоже не сработало. Вы имели в виду, что я тоже должен удалить акт выхода?

3. вы не должны оборачивать весь свой текст действием . удалите этот » акт ожидания(асинхронный () => {`

4. @coding1223322 Пара вещей не так с вашим тестом, в дополнение к тому , что уже было предложено: 1) Вам не нужно явно вызывать mockGetMovies , это будет сделано компонентом, который вы тестируете; 2) Завершите expect(container).toMatchInlineSnapshot(...) вызов await waitFor(() => ...) — это обеспечит выполнение асинхронной операции внутри компонента useEffect .