Тестирование нескольких запросов на выборку в шутку

#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>
    </>
  );
};