如何编写 spyOn 自定义钩子
How to write spyOn custom hook
我有一个自定义挂钩
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();
});
});
在此测试中,我想监视我的自定义挂钩并断言该组件尝试设置有效标题。
使用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/Whosebug/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
我有一个自定义挂钩
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();
});
});
在此测试中,我想监视我的自定义挂钩并断言该组件尝试设置有效标题。
使用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/Whosebug/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