#reactjs #jestjs #react-testing-library #testing-library
Вопрос:
Я не могу найти никаких статей или документации о том, как протестировать несколько синхронных запросов на выборку в a useEffect
. Я извлекаю данные, а затем, прежде чем начнется вторая выборка, я устанавливаю всплывающую подсказку «загрузка данных» на кнопке. Как только вторая выборка завершена, всплывающая подсказка превращается либо в «не удается использовать эту функцию», либо ее вообще нет. Я не уверен, как перейти в те состояния теста, в которых шутка находится до или после вызова выборки.
Проблема в том, что мой тест не видит всплывающую подсказку «загрузка данных» для начала, хотя она появляется, когда я тестирую ее вручную. Мне трудно понять, когда ждать второго звонка, и когда это действительно произойдет, и когда он закончится…
Просто для уточнения getAccountInfo
— это функция запроса выборки, которая возвращает объект со accountInfo
свойством.
Ошибка:
TestingLibraryElementError: Не удается найти элемент с текстом: /загрузка данных/. Это может быть связано с тем, что текст разбит на несколько элементов. В этом случае вы можете предоставить функцию для сопоставления текста, чтобы сделать его более гибким.
Вот мой тест
import React from 'react';
import * as utils from '../utils';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import fetch from 'jest-fetch-mock';
const getAccountInfoSpy = jest.spyOn(utils, 'getAccountInfo');
const testId = 'ABCDEF';
describe('AccountInfo', () => {
beforeAll(() => fetch.enableMocks());
afterAll(() => fetch.disableMocks());
beforeEach(() => jest.clearAllMocks());
it('displays "loading data" tooltip on hover' () => {
fetch.mockResponse(
JSON.stringify({
orgId: testId,
name: 'Adam',
}),
{ status: 200 },
);
const { getByRole, findByText } = render(
<AccountInfo />
);
const importButton = getByRole('button', { name: 'Import' });
fireEvent.mouseEnter(importButton);
expect(await findByText(/loading data/)).toBeInTheDocument();
await waitFor(() =>
expect(getAccountInfoSpy).toHaveBeenCalledWith(testId),
);
expect(findByText(/cannot use this feature/).toBeInTheDocument();
});
});
Вот компонент AccountInfo
const AccountInfo = () => {
const { customerId } = useCustomerContext();
const [isLoading, setIsLoading] = useState(true);
const [accountInfo, setAccountInfo] = useState({});
const [isAccountInfoLoading, setIsAccountInfoLoading] = useState(false);
useEffect(() => {
const fetchAccountData = async () => {
const rawRes = await fetch(`/customer/${customerId}`);
const res = await rawRes.json();
setIsLoading(false);
if (res.orgId) {
setIsAccountInfoLoading(true);
try {
const accountInfoRes = await getAccountInfo(res.orgId);
setAccountInfo(accountInfoRes.accountInfo);
} catch (error) {
console.log('error', error);
} finally {
setIsAccountInfoLoading(false);
}
}
}
fetchAccountData();
});
function renderTooltip() {
if (isAccountInfoLoading) {
return 'loading data';
} else {
return !accountInfo.active
? 'cannot use this feature'
: undefined;
}
}
return (
<>
<Button tooltip={renderTooltip()}>
Import
</Button>
</>
);
};