Тестирование пользовательского хука с библиотекой реагировать-хуки-тестирование выдает ошибку - PullRequest
2 голосов
/ 11 мая 2019

Я пытаюсь протестировать простой хук, который выбирает некоторые данные, используя 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);
    });
});

Пожалуйста, помогите мне понять, как в этом случае использовать реагирующую ловушку-тестирующую библиотеку.

Редактировать

Похоже, это связано с проблемой Jest, которая, казалось бы, была решена. Пожалуйста, смотрите https://github.com/facebook/jest/pull/3209.

1 Ответ

2 голосов
/ 13 мая 2019

The

TypeError: "Невозможно прочитать свойство '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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...