【问题标题】:How can I mock an react hook using Jest?如何使用 Jest 模拟反应钩子?
【发布时间】:2020-01-17 08:46:40
【问题描述】:

我有一个请求数据的组件。成功获取数据后应显示通知。出于这个原因,我们有一个名为 @my-company/notifications 的包(在纱线工作区中)。

import { useNotification } from '@my-company/notifications';

const ComponentWithDataFetching = () => {
  const {
    enqueueInfoNotification,
  } = useNotification();
  const {
    data,
  } = useQuery({
    onCompleted: () => {
      enqueueInfoNotification({ message: 'Data successfully fetch' });
    },
  })
}

我想测试一下

import { useNotification } from '@my-company/notifications';
import { render, fireEvent, act, wait } from '@testing-library/react';

jest.mock('@my-company/notifications', () => ({
  useNotification() {
    return {
      enqueueInfoNotification: jest.fn(),
    };
  },
}));

describe('<ComponentWithDataFetching />', () => {
  it('should enqueue info notification', async () => {
    const { getByTestId } = render(
      <TestSuitWrapper>
        <ComponentWithDataFetching />
      </TestSuitWrapper>,
    );

    expect(useNotification).toBeCalled();
  });
});

测试运行时,会发生错误: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

如果删除 jest.mock 测试开始时没有错误。如何模拟测试调用 enqueueInfoNotification 函数的反应钩子?

【问题讨论】:

    标签: reactjs unit-testing jestjs


    【解决方案1】:

    你可以做的是你可以模拟@mycompany/notifications模块,在测试中你可以实现它来返回一个名为enqueueInfoNotification的模拟函数并测试它是否被调用。但是你也应该模拟 useQuery ,你可以使用 apollo-react-tesing 包来做到这一点

    import { useNotification } from '@mycompany/notifications';
    import { render, fireEvent, act, wait } from '@testing-library/react';
    
    jest.mock('@astral-frontend/notifications');
    
    describe('<ComponentWithDataFetching />', () => {
      it('should enqueue info notification', async () => {
        useNotification.mockReturnValue({
           enqueueInfoNotification: jest.fn()
        });
    
        render(
          <TestSuitWrapper>
            <ComponentWithDataFetching />
          </TestSuitWrapper>,
        );
    
        expect(useNotification.enqueueInfoNotification).toBeCalled();
      });
    });
    
    

    【讨论】:

    • 谢谢你,但现在我又遇到了一个错误NotificationsProvider(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, ret urn null. 因为从@my-company/notifications 导入NotificationsProviderjest.mock 可能会覆盖这个。
    • 两个简单的操作效果很好:1)import NotificationsProvider from '@my-company/notifications/src/NotificationsProvider'; 2)expect(useNotification().enqueueInfoNotification.mock.calls.length).toBe(1);
    • 是的,如果您添加提供程序并将一些模拟数据作为道具添加到提供程序,那么错误就会消失
    猜你喜欢
    • 1970-01-01
    • 2019-12-30
    • 2021-05-11
    • 2020-07-07
    • 2021-10-10
    • 2022-01-06
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    相关资源
    最近更新 更多