#reactjs #axios #jestjs #react-hooks #react-testing-library
Вопрос:
моя проблема
Я хочу написать тест (с библиотекой тестирования реакции и шуткой), чтобы убедиться, что мой запрос get получает список json-объектов (длиной > 400).>
Код для этого представлен ниже.
Проблема в том, что я получаю сообщение об ошибке: «Время ожидания истекло».
Что я делаю не так?, Я благодарен за любую помощь и/или руководство.
import React {useEffect, useState} from 'react';
import Axios from 'axios';
const TestComp = () => {
const [data, setData] = useState([]);
useEffect(()=>{
Axios.get("/../someURL").then((res) => {
setData(res.data);
})
});
return (
<table>
{state.data.map(d => (
<tr>
<th>
{data.req_id}
</th>
</tr>
))}
</table>
);
};
import React from 'react';
import {render, screen, waitFor} from '@testing-library/react';
import TestComp from "./../TestComp";
test("test", async () => {
render(<TestComp/>);
await waitFor(async() => {
const receivedRows = await screen.findAllByRole("row");
const nrOfReceivedRows = receivedRows.length;
expect(nrOfReceivedRows > 400).toBeTruthy();
// I have also tried expect(nrOfReceivedRows).toBeGreaterThan(400);
});
})
Комментарии:
1. Вы делаете реальный запрос в тесте для TestComp и, если да, то почему?
2. Да, точно, это реальный запрос, я новичок в тестировании, и я подумал, что было бы разумно сделать реальный запрос, потому что тогда я смогу знать (всякий раз, когда я буду запускать тест), не работает ли серверная часть или интерфейс.
3. @jonrsharpe , возможно, я думаю об этом неправильно?
4. Я бы так сказал, потому что прямо сейчас тест проваливается, и вы не можете сказать, в чем проблема-в бэкэнде или в интерфейсе. Кроме того, реальные сетевые запросы, как правило, на порядки медленнее, чем вы ожидаете от тестов на уровне модулей. Я бы рекомендовал провести тесты E2E, которые проверяют, что все работает вместе, но на этом уровне вам, вероятно, следует подумать о насмешках на сетевом уровне (например
msw
) или о том, чтобы создать фасад вокруг Axios, который вы можете создать сами. Я написал о тестировании приложений React таким образом в своем блоге: blog.jonrshar.pe/2021/Apr/10/js-tdd-api.html
Ответ №1:
В вашем коде есть некоторые проблемы:
<tr>
не может появиться в качестве ребенка<table>
. Добавьте a<tbody>
<thead>
или<tfoot>
в свой код , чтобы он соответствовал дереву DOM, созданному браузером.findBy
методы представляют собой комбинациюgetBy
запросов иwaitFor
. Они принимаютwaitFor
варианты в качестве последнего аргумента (напримерawait screen.findByText('text', queryOptions, waitForOptions)
). Вам не нужно использоватьwaitFor
иfindBy
запрашивать вместе. См. Раздел Поисковые запросы- Для модульного тестирования вы НЕ должны вызывать реальную внешнюю службу, такую как (вызов API, запрос бд и т. Д.). Эти услуги с побочными эффектами должны быть высмеяны или заглушены. Таким образом, ваши тесты могут выполняться в изолированной среде, не полагаясь на внешние реальные службы. Тест, который вызывает реальную службу, должен быть тестом E2E.
Таким образом, пример модульного теста используется jest.spyOn()
для axios.get
моделирования метода и его разрешенного/отклоненного значения.
TestComp.jsx
:
import React, { useEffect, useState } from 'react';
import Axios from 'axios';
export const TestComp = () => {
const [data, setData] = useState([]);
useEffect(() => {
Axios.get('/../someURL').then((res) => {
console.log(res);
setData(res.data);
});
}, []);
return (
<table>
<tbody>
{data.map((d) => (
<tr key={d.req_id}>
<th>{d.req_id}</th>
</tr>
))}
</tbody>
</table>
);
};
TestComp.test.jsx
:
import React from 'react';
import Axios from 'axios';
import { render, screen } from '@testing-library/react';
import { TestComp } from './TestComp';
test('test', async () => {
const getSpy = jest.spyOn(Axios, 'get').mockResolvedValueOnce({
data: Array(401)
.fill()
.map((d, idx) => ({ req_id: idx })),
});
render(<TestComp />);
const receivedRows = await screen.findAllByRole('row');
expect(receivedRows.length > 400).toBeTruthy();
getSpy.mockRestore();
});
результат теста:
console.log
{
data: [
{ req_id: 0 }, { req_id: 1 }, { req_id: 2 }, { req_id: 3 },
{ req_id: 4 }, { req_id: 5 }, { req_id: 6 }, { req_id: 7 },
{ req_id: 8 }, { req_id: 9 }, { req_id: 10 }, { req_id: 11 },
{ req_id: 12 }, { req_id: 13 }, { req_id: 14 }, { req_id: 15 },
{ req_id: 16 }, { req_id: 17 }, { req_id: 18 }, { req_id: 19 },
{ req_id: 20 }, { req_id: 21 }, { req_id: 22 }, { req_id: 23 },
{ req_id: 24 }, { req_id: 25 }, { req_id: 26 }, { req_id: 27 },
{ req_id: 28 }, { req_id: 29 }, { req_id: 30 }, { req_id: 31 },
{ req_id: 32 }, { req_id: 33 }, { req_id: 34 }, { req_id: 35 },
{ req_id: 36 }, { req_id: 37 }, { req_id: 38 }, { req_id: 39 },
{ req_id: 40 }, { req_id: 41 }, { req_id: 42 }, { req_id: 43 },
{ req_id: 44 }, { req_id: 45 }, { req_id: 46 }, { req_id: 47 },
{ req_id: 48 }, { req_id: 49 }, { req_id: 50 }, { req_id: 51 },
{ req_id: 52 }, { req_id: 53 }, { req_id: 54 }, { req_id: 55 },
{ req_id: 56 }, { req_id: 57 }, { req_id: 58 }, { req_id: 59 },
{ req_id: 60 }, { req_id: 61 }, { req_id: 62 }, { req_id: 63 },
{ req_id: 64 }, { req_id: 65 }, { req_id: 66 }, { req_id: 67 },
{ req_id: 68 }, { req_id: 69 }, { req_id: 70 }, { req_id: 71 },
{ req_id: 72 }, { req_id: 73 }, { req_id: 74 }, { req_id: 75 },
{ req_id: 76 }, { req_id: 77 }, { req_id: 78 }, { req_id: 79 },
{ req_id: 80 }, { req_id: 81 }, { req_id: 82 }, { req_id: 83 },
{ req_id: 84 }, { req_id: 85 }, { req_id: 86 }, { req_id: 87 },
{ req_id: 88 }, { req_id: 89 }, { req_id: 90 }, { req_id: 91 },
{ req_id: 92 }, { req_id: 93 }, { req_id: 94 }, { req_id: 95 },
{ req_id: 96 }, { req_id: 97 }, { req_id: 98 }, { req_id: 99 },
... 301 more items
]
}
at examples/68312820/TestComp.jsx:8:15
PASS examples/68312820/TestComp.test.jsx (9.507 s)
✓ test (799 ms)
--------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
TestComp.jsx | 100 | 100 | 100 | 100 |
--------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.181 s