#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
.