При тестировании пользовательского хука с помощью библиотеки activ-hooks-testing-error выдается ошибка
Я пытаюсь протестировать простой хук, который выбирает некоторые данные, используя axios. Однако в тесте выдается ошибка TypeError: "Невозможно прочитать свойство fetchCompanies из undefined". Вот мой пользовательский хук ( полное репо здесь):
import { useState, useEffect } from 'react';
import { Company } from '../../models';
import { CompanyService } from '../../services';
export const useCompanyList = (): {
loading: boolean;
error: any;
companies: Array<Company>;
} => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState();
const [companies, setCompanies] = useState<Array<Company>>([]);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const companies = await CompanyService.fetchCompanies();
// Sort by ticker
companies.sort((a, b) => {
if (a.ticker < b.ticker) return -1;
if (a.ticker > b.ticker) return 1;
return 0;
});
setCompanies(companies);
setLoading(false);
} catch (e) {
setError(e);
}
};
fetchData();
}, []);
return { loading, error, companies };
};
и вот мой тест:
import { renderHook } from 'react-hooks-testing-library';
import { useCompanyList } from './useCompanyList';
const companiesSorted = [
{
ticker: 'AAPL',
name: 'Apple Inc.'
},
...
];
jest.mock('../../services/CompanyService', () => {
const companiesUnsorted = [
{
ticker: 'MSFT',
name: 'Microsoft Corporation'
},
...
];
return {
fetchCompanies: () => companiesUnsorted
};
});
describe('useCompanyList', () => {
it('returns a sorted list of companies', () => {
const { result } = renderHook(() => useCompanyList());
expect(result.current.loading).toBe(true);
expect(result.current.error).toBeUndefined();
expect(result.current.companies).toEqual(companiesSorted);
});
});
Пожалуйста, помогите мне понять, как в этом случае использовать response-hooks-testing-library.
редактировать
Похоже, это связано с проблемой Jest, которая, казалось бы, была решена. Пожалуйста, смотрите https://github.com/facebook/jest/pull/3209.
1 ответ
Ошибка типа: "Не удается прочитать свойство 'fetchCompanies' из неопределенного"
вызвано тем, как вы определяете CompanyService
оказание услуг. В коде вы экспортируете объект CompanyService
со всеми методами обслуживания. Но в вашем тесте вы издеваетесь CompanyService
вернуть объект с методами.
Итак, макет должен вернуть CompanyService
объект, который является объектом со всеми методами:
jest.mock('../../services/CompanyService', () => {
const companiesUnsorted = [
{
ticker: 'MSFT',
name: 'Microsoft Corporation'
},
...
];
return {
CompanyService: {
fetchCompanies: () => companiesUnsorted
}
};
});
Теперь, когда вы решите это, вы обнаружите, что у вас нет TypeError
больше, но ваш тест не проходит. Это потому, что код, который вы пытаетесь протестировать, является асинхронным, а ваш тест - нет. Итак, сразу после рендеринга renderHook
) result.current.companies
будет пустой массив.
Вам придется подождать, пока ваше обещание не будет решено. К счастью, react-hooks-testing-library
дает нам waitForNextUpdate
функция для того, чтобы ждать следующего обновления хука. Итак, окончательный код теста будет выглядеть так:
it('returns a sorted list of companies', async () => {
const { result, waitForNextUpdate } = renderHook(() => useCompanyList());
expect(result.current.loading).toBe(true);
expect(result.current.error).toBeUndefined();
expect(result.current.companies).toEqual([]);
await waitForNextUpdate();
expect(result.current.loading).toBe(false);
expect(result.current.error).toBeUndefined();
expect(result.current.companies).toEqual(companiesSorted);
});