【问题标题】:How to write spyOn custom hook如何编写 spyOn 自定义钩子
【发布时间】:2020-10-07 13:31:34
【问题描述】:

我有一个自定义钩子

import { useDispatch } from 'react-redux';
import { SET_APP_TITLE } from '../reducers/appBar';

export const useTitle = (title: string) => {
  const dispatch = useDispatch();
  return dispatch({ type: SET_APP_TITLE, title });
};

以及使用它的组件

import { useTitle } from '../common/useTitle';
export default () => {
  useTitle('Dashboard');
  return <div>Dashboard</div>
}

现在我想为组件编写单元测试(使用 Jest 和 React 测试库):

import React from 'react';
import { render } from '@testing-library/react';
import Dashboard from './Dashboard';
import { useTitle } from '../commons/useTitle';

describe('Dashboard', () => {
  it('renders without crashing', () => {
    const { getByText } = render(<Dashboard />);
    expect(getByText('Dashboard')).toBeInTheDocument();
  });
});

在这个测试中,我想监视我的自定义钩子并断言该组件试图设置有效的标题。

【问题讨论】:

    标签: reactjs unit-testing jestjs react-hooks react-testing-library


    【解决方案1】:

    使用jest.mock(moduleName, factory, options) 模拟../commons/useTitle 模块。 useTitle 自定义挂钩将在您导入并在测试文件中使用时被模拟。

    例如

    useTitle.ts:

    import { useDispatch } from 'react-redux';
    
    const SET_APP_TITLE = 'SET_APP_TITLE';
    
    export const useTitle = (title: string) => {
      const dispatch = useDispatch();
      return dispatch({ type: SET_APP_TITLE, title });
    };
    

    Dashboard.tsx:

    import React from 'react';
    import { useTitle } from './useTitle';
    
    export default () => {
      useTitle('Dashboard');
      return <div>Dashboard</div>;
    };
    

    Dashboard.test.tsx:

    import '@testing-library/jest-dom/extend-expect';
    import React from 'react';
    import { render } from '@testing-library/react';
    import Dashboard from './Dashboard';
    import { useTitle } from './useTitle';
    
    jest.mock('./useTitle');
    
    describe('Dashboard', () => {
      it('renders without crashing', () => {
        const { getByText } = render(<Dashboard />);
        expect(getByText('Dashboard')).toBeInTheDocument();
        expect(jest.isMockFunction(useTitle)).toBeTruthy();
        expect(useTitle).toBeCalledWith('Dashboard');
      });
    });
    

    带有覆盖率报告的单元测试结果:

     PASS  src/stackoverflow/64228834/Dashboard.test.tsx (17.901s)
      Dashboard
        ✓ renders without crashing (43ms)
    
    ---------------|----------|----------|----------|----------|-------------------|
    File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ---------------|----------|----------|----------|----------|-------------------|
    All files      |       80 |      100 |       50 |       80 |                   |
     Dashboard.tsx |      100 |      100 |      100 |      100 |                   |
     useTitle.ts   |       60 |      100 |        0 |       60 |               6,7 |
    ---------------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        19.534s, estimated 20s
    

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 2021-03-15
      • 1970-01-01
      • 2015-03-24
      • 2021-04-07
      • 1970-01-01
      • 2020-08-04
      • 2020-08-09
      • 2013-05-01
      相关资源
      最近更新 更多