#testing #jestjs #react-hooks #automated-tests #react-hooks-testing-library
Вопрос:
Я не очень хорошо пишу тесты, что касается функций, не связанных с API, я тестировал с помощью JEST с помощью rendererHook, как показано ниже, Пример правильного ТЕСТА:
import { render, screen, cleanup } from '@testing-library/react';
import useAppDrawer from "../../../utils/hooks/useAppDrawer";
import {act,renderHook} from '@testing-library/react-hooks';
import React from "react";
describe("hook: useAppDrawer", () => {
afterEach(() => {
cleanup();
});
test('drawer open', () => {
const {result} = renderHook(useAppDrawer);
act(()=>{
result.current.handleDrawerOpen();
})
expect(result.current.open).toBe(true);
});
test('drawer close', () => {
const {result} = renderHook(useAppDrawer);
act(()=>{
result.current.handleDrawerClose();
})
expect(result.current.open).toBe(false);
});
});
Но что мы будем делать в случае вызовов API в ШУТКУ, что все еще сбивает меня с толку. Я все еще не могу понять, как я могу тестировать вызовы API в ШУТКУ, как это показано ниже, Проблемная функция:
import React, {useContext} from "react";
import request from "../services/Http";
import useIsLoading from "./useIsLoading";
import {Context} from "../store/context/store";
import {SET_BOOTHS} from "../store/context/Constants";
export default function useFetchBooths(){
const {isLoading, setIsLoading} = useIsLoading()
const [{booths}, dispatch] = useContext(Context)
function fetchBooths(){
setIsLoading(true)
request.get('/event/get-booth-list')
.then((res) => {
setIsLoading(false)
if (res)
{
dispatch({
type: SET_BOOTHS,
payload: res.data.booth_data
})
}
})
}
function searchBooths(value){
if (value)
{
let obj = booths.filter(booth => booth.booth_name.toLowerCase().includes(value.toLowerCase()));
if (obj.length > 0)
{
dispatch({
type: SET_BOOTHS,
payload: obj
})
}
else
{
fetchBooths()
}
}
else
{
fetchBooths()
}
}
return { booths, fetchBooths, isLoading, searchBooths }
}
what would be the possible jest test for the above function? considering cases like if booth is fetched or not as in both cases I am getting booth value to be [].
My attempt so far for this is:
import { render, screen, cleanup, waitFor } from '@testing-library/react';
import useFetchBooths from "../../../utils/hooks/useFetchBooths";
import {act,renderHook} from '@testing-library/react-hooks';
import React from "react";
import * as requestsModule from "../../../utils/services/Http";
import {Store} from "../../../utils/store/context/store";
describe("hook: useFetchBooths", () => {
afterEach(() => {
cleanup();
});
test('Booth is fetched', async () => {
const boothData = [
{
"message": "Data fetched Successfully",
"success": true
}
];
const wrapper = ({children}) => (
<Store>{children}</Store>
)
const {result } = renderHook(() => useFetchBooths(), {wrapper});
jest.spyOn(result.current, "fetchBooths").mockResolvedValue(boothData);
console.log(result.current.fetchBooths())
await expect(result.current.fetchBooths()).resolves.toEqual([{ "success": true, "message": "Data fetched Successfully" }]);
});
});
Выше тест пройден, но это издевались по API(я создаю данные и сравнивая его с моим собственным письменных данных, но это не я хочу), но я хочу, чтобы мой фактический API работает или нет в этот тест, как я извлечения Бут список в fetchBooths() функцию, так как я могу проверить его с притворным API, когда мои все зависит от реального API, который я хочу протестировать его, проверив мой фактический API на самом деле работает или нет в том, что тест с помощью некоторых асинхронный/ждут , но я сильно застрял в этой точке. Кроме того, я не могу понять, каким будет тестовый случай для функции Searchboots, поскольку она выглядит неопределенной и список стендов отображается как [], хотя это не должно быть [], я все еще не могу найти решение. Пожалуйста, помогите мне написать эти тестовые примеры
Комментарии:
1. что бы вы хотели проверить здесь? Я предполагаю, что вас не интересует
makeStyles
само тестирование2. @thedude Я все еще не могу понять, как мы можем написать тест для вызовов API в ШУТКУ. Точно так же, как я написал выше, функция fetchboots (), как я могу писать тесты для нее, учитывая такие случаи, как, если выбран стенд или нет, так как в обоих случаях я получаю значение booth равным [].
3. @thedude Я обновил вопрос. Не могли бы вы, пожалуйста, помочь мне сейчас?
4. Я бы посмотрел,
jest.spyOn
чтобы высмеятьrequest.get
и утверждать, что он был вызван с правильным вводом. Такой же подход можно было бы применить для тестированияmakeStyles
5. @thedude не могли бы вы, пожалуйста, подробнее рассказать, например, о том, как я исправил свой код, учитывая мою попытку, описанную выше, например, я могу войти в загрузочный комплект fetchboots(true), но не могу ничего получить из запроса. Дайте мне знать, если возможно, чтобы я мог поделиться с вами своим экраном?
Ответ №1:
В своем тестовом коде используйте a spy
для макетирования модуля запросов:
import * as requestsModule from "../services/Http";
describe("hook: useFetchBooths", () => {
afterEach(() => {
cleanup();
});
test('Booth is fetched', async () => {
jest.spyOn(requestsModule, 'get').mockResolvedValue([]) // <-- here you should provide the data you want your hook to see.
const wrapper = ({children}) => (
<Store>{children}</Store>
)
const {result } = renderHook(() => useFetchBooths(), {wrapper});
await act(async () => {
await waitFor(() => result.current.fetchBooths() )
})
await act(async () => {
await waitFor(() => result.current.booths )
console.log(result.current);
})
expect(result.current.booths).toEqual([]);
});
});
Обновление: как издеваться над useContext
- создайте пользовательский крючок
// boothsContext.js
import {Context} from "../store/context/store";
export const useBoothsContext = () => useContext(Context)
- издевайтесь над крючком, используя
jest.spyOn
:
import { wait } from '@testing-library/react'
import * as BoothsContextModule from './boothsContext.js'
...
test('Booth is fetched', async () => {
const mockDispatch = jest.fn()
const data = { booths: []} // change this to inject different data into your hook result
jest.spyOn(BoothsContextModule, 'useBoothsContext')
.mockReturnValue([data, mockDispatch])
// perform test steps
await wait(() => expect(mockDispatch).toHaveBeenCalledWith({
type: SET_BOOTHS,
payload: {...} // <-- expected payload you want to assert
}))
Комментарии:
1. не могу ли я просто проверить что-то вроде того, что если данные будут извлечены, и получить «сообщение»: «Данные получены успешно», то я просто пройду тест ? как я должен добиться этого здесь в ШУТКУ?
2. Я передаю данные, как jest.spyOn(requestsModule, ‘get’).mockResolvedValue({данные:{«успех»: истина, «сообщение»: «Данные получены успешно»},»booth_data»: [ { «booth_id»: «8818», «имя пользователя»: «Изменено», }] }); но я попадаю в ошибку » Ошибка: Не удается обнаружить свойство get, потому что оно не является функцией; вместо этого задано неопределенное »
3. как я буду сравнивать эти издевательские значения с фактическими, чтобы добавить «ожидаемое условие» для передачи, сравнивая исходные данные с издевательскими данными? Не могли бы вы, пожалуйста, обновить ответ как для функции поиска, так и для функции извлечения, включая ожидаемое условие, которое должно быть выполнено для прохождения теста, я буду вам очень благодарен. Если вы спросите, я могу поделиться с вами своим экраном через TeamViewer или что-то в этом роде
4. Я все еще застрял, я обновил свою попытку в соответствии с вашим руководством, и у меня также есть вопрос, если мы просто издеваемся над API, то как мы просто проверим, работает ли реальный API или нет, как я также хочу убедиться, что мой реальный API работает в этом функциональном тесте, что является моей главной проблемой, используя какое-то асинхронное ожидание. Кроме того, каким будет тестовый случай для функции Searchboots Я также запутался при написании этого теста, я упомянул этот файл, о котором идет речь, с жирным названием «Проблемная функция», для которой я хочу написать тест. Любая помощь будет очень признательна
5. Похоже, вы на самом деле не пишете модульные тесты. Лучшая практика-разбить ваш код на блоки, которые можно тестировать отдельно. Если вы действительно хотите вызвать свой API, то вместо того, чтобы издеваться над запросами get, вы можете издеваться над
useContext
крючком и проверять, был ли сделан правильныйdispatch
вызов