reactjs - 如何在 React 中用 Jest 和 Enzyme 测试这样的组件?
问题描述
我有一个 React Scroll to Top 组件,我们将这个组件添加到我们的路由器下方,以便在跨页面移动时我们不保持滚动位置。
我试图为此组件编写测试用例,但是在进行浅层渲染时,Jest 和 Enzyme dosent 似乎将其识别为组件。我正在使用打字稿,这是组件。
scrollToTop.ts
export const ScrollToTop = ({history}: IRouterResetScroll) => {
useEffect(() => {
const unListen = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unListen();
}
}, []);
return null;
}
export default withRouter(ScrollToTop);
解决方案
这是我的单元测试策略,要测试的代码最难的部分是history.listen(handler)
,所以我们可以模拟history.listen
方法的实现,我们定义了 aqueue
来存储处理程序。挂载组件后,模拟历史将以history.listen
函数作为参数执行。这个函数会保存在queue
我们之前定义的里面。我们可以从单元测试用例的队列中获取这个函数并手动触发它。
index.tsx
:
import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';
type IRouterResetScroll = any;
export const ScrollToTop = ({ history }: IRouterResetScroll) => {
useEffect(() => {
const unListen = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unListen();
};
}, []);
return null;
};
export default withRouter(ScrollToTop);
index.spec.tsx
:
import React from 'react';
import { ScrollToTop } from './';
import { mount } from 'enzyme';
describe('ScrollToTop', () => {
it('should scroll to top', () => {
const queue: any[] = [];
const mUnListen = jest.fn();
const mHistory = {
listen: jest.fn().mockImplementation(fn => {
queue.push(fn);
return mUnListen;
})
};
window.scrollTo = jest.fn();
const wrapper = mount(<ScrollToTop history={mHistory}></ScrollToTop>);
queue[0]();
expect(mHistory.listen).toBeCalledWith(expect.any(Function));
expect(window.scrollTo).toBeCalledWith(0, 0);
wrapper.unmount();
expect(mUnListen).toBeCalledTimes(1);
});
});
覆盖率 100% 的单元测试结果:
PASS src/stackoverflow/58786973/index.spec.tsx
ScrollToTop
✓ should scroll to top (39ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 4.041s, estimated 9s
源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58786973
推荐阅读
- node.js - Visual Studio node.js“断点设置但尚未绑定”
- r - 基于特定列从df中删除0值的基本功能
- reactjs - useState() 钩子值落后 1 步,已经在使用 useEffect()
- python - 从嵌套字典结构列表(具有两个级别)创建数据框的 Pythonic 方法是什么?
- curl - 来自服务器的空回复:在 Openshit 4.9 ServiceMesh v2.1.0 Istio Sidecar Proxy curling to frontend container in the same pod
- algorithm - 具有有限“临时”空间的 Bin 重新打包算法
- python - 优化 Python 列表中的查找和合并
- unit-testing - Jest 单元测试在组件导入语句上失败
- spring-boot - STS 以 79% 停留在“导入入门内容”
- python - 如何将日期指定为 json 中的数据类型