如何编写spyOn自定义钩子

时间:2020-10-06 15:19:35

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

我有一个自定义钩子

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 Testing库):

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();
  });
});

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

1 个答案:

答案 0 :(得分:0)

使用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