React Jest: как мне имитировать асинхронный вызов API, который возвращает данные?

#reactjs #user-interface #async-await #jestjs

#reactjs #пользовательский интерфейс #async-await #jestjs

Вопрос:

Я пытаюсь протестировать компонент React table (который использует асинхронный вызов API для возврата данных таблицы), но не могу понять, как имитировать вызов API, чтобы удовлетворить мой тестовый файл React. У меня есть файл макета данных для предоставления макетных данных. (Я включил только соответствующий код).

mockData:

 const mockRequestData = [
    {
        "email": "runner1@test.com",
        "firstName": "runner1",
        "lastName": "runner1"
    },
    {
        "email": "runner2@test.com",
        "firstName": "runner2",
        "lastName": "runner2"
    },
    {
        "email": "runner3@test.com",
        "firstName": "runner3",
        "lastName": "runner3"
    },
];

export const mockData = {
    mockData: mockRequestData,
};
  

ApiCall находится в своем собственном файле:

 const getAllAthletesSigningUp = async () => {
    let athletesSigningUp= [];

    const response = await returnGetResponse("/api/atheletesignup");
    if (response.status === 200) {
        return athletesSigningUp= (response.body);
    }
    return athletesSigningUp
};

export {getAllAthletesSigningUp};
  

Приложение для запуска:

  const [requests, setRequests] = useState([]);

    useEffect( () => {
        apiResponse();
    },[]);

    const apiResponse = async () => {
        return setRequests(await getAllAthletesSigningUp ())
    }


<div className={"table_content"}>
                {
                  requests.map((request, index) => {
                       return (
                          <>
                              <div key={index} className={"table_row"} data-testid={"tableRow"}>
                                  <p>{formatText(request.email)}</p>
                                  <p>{formatText(request.firstName)}</p>
                                  <p>{formatText(request.lastName)}</p>
  

Ответ №1:

Вы можете использовать jest.mock() :

 jest.mock(<path to getAllAthletesSigningUp>, () => ({
  getAllAthletesSigningUp: jest.fn(() => [<mock data>])
}))

describe('...', () => {
  it('...', () => {
    // const {getAllAthletesSigningUp} = jest.requireMock(<path>) - if You need mocked implementation in test;
    // const {getAllAthletesSigningUp} = jest.requireActual(<path>) - if You need original implementation in test;
  })
})
  

или описать реализацию непосредственно в одном тесте с mockImplementation помощью или mockImplementationOnce() :

 jest.mock(<path to getAllAthletesSigningUp>, () => ({
  getAllAthletesSigningUp: jest.fn()
}))

describe('...', () => {
  it('...', () => {
    const {getAllAthletesSigningUp} = jest.requireMock(<path>)
    // getAllAthletesSigningUp.mockImplementation(() => [<mock data>]) - for all function calls;
    // getAllAthletesSigningUp.mockImplementationOnce(() => [<mock data>]) - for single function call;
  })
})
  

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

1. Я попробовал ваш второй вариант, но я получаю эту ошибку: свойство ‘mockImplementationOnce’ не существует для типа ‘() => Обещание<любое>’.