测试使用 jQuery 和窗口对象的 React 组件
Testing a React component that uses jQuery & window object
我的 React 组件必须响应resize
事件,为此我使用 jQuery,即:
//...
componentDidMount: function() {
$(window).on("resize", function);
}
//..
但是,这会导致我的 Jest 测试出现问题,特别是:
- TypeError: Cannot read property 'on' of undefined
at RadiumEnhancer.React.createClass.componentDidMount (bundles/Opportunities/OpportunityPartial.jsx:21:14)
单步执行测试时,看起来像是在开玩笑测试中定义了窗口,但$(window)
似乎没有返回任何内容。
我的印象是 Jest 会检查所需的模块 (jQuery) 的 API 来构建其模拟,但如果我正确理解问题,似乎这并没有发生?
我可以通过不嘲笑jQuery来解决这个问题,但显然这并不完全可取。
以下是使用 jestjs
和 enzyme
的单元测试解决方案:
index.tsx
:
import React, { Component } from 'react';
import $ from 'jquery';
class SomeComponent extends Component {
componentDidMount() {
$(window).on('resize', this.resizeEventHandler);
}
resizeEventHandler() {
console.log('resize event handler');
}
render() {
return <div>some component</div>;
}
}
export default SomeComponent;
index.spec.tsx
:
import React from 'react';
import SomeComponent from './';
import { shallow } from 'enzyme';
import $ from 'jquery';
jest.mock('jquery', () => {
const m$ = {
on: jest.fn(),
};
return jest.fn(() => m$);
});
describe('36082197', () => {
afterEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});
it('should pass', () => {
const logSpy = jest.spyOn(console, 'log');
const eventHandlerMap = {};
($().on as jest.MockedFunction<any>).mockImplementation((event, handler) => {
eventHandlerMap[event] = handler;
});
const wrapper = shallow(<SomeComponent></SomeComponent>);
const instance = wrapper.instance();
expect(wrapper.text()).toBe('some component');
expect($).toBeCalledWith(window);
// tslint:disable-next-line: no-string-literal
expect($(window).on).toBeCalledWith('resize', instance['resizeEventHandler']);
eventHandlerMap['resize']();
expect(logSpy).toBeCalledWith('resize event handler');
});
});
100% 覆盖率的单元测试结果:
PASS src/stackoverflow/36082197/index.spec.tsx (12.045s)
36082197
✓ should pass (18ms)
console.log node_modules/jest-mock/build/index.js:860
resize event handler
-----------|----------|----------|----------|----------|-------------------|
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: 14.267s, estimated 15s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/36082197
相关文章:
- 在react函数中渲染对象数组
- React-从简单对象树创建dom
- 在React中渲染子对象,丢失道具数据
- 访问要在 React Native Text 组件中显示的对象数组
- React.js+Flux-正确初始化存储中的数据对象
- React选择性地不将新道具传递给渲染对象
- TypeError:undefined不是对象(正在评估'this.props')-React Nati
- 如何从 React 中的事件对象访问自定义属性
- React是装载前处理空对象的最佳方式
- 从react routers browserHistory对象获取当前页面路径
- 测试使用 jQuery 和窗口对象的 React 组件
- JSON 对象 - 在 React Native 中访问值
- 在 React Native 中对对象数组进行动画处理
- 使用 Javascript/React.js 查找对象的数组索引
- 使用 React 创建的表单不会更新支持状态对象
- 在 react 中对字符串应用 span 会返回 [对象对象],而不是给我跨度文本
- 在 React 中从数组中删除对象
- 通过带有对象子级的数组进行 React 本机映射 - 工作方式与在 react web 中不同
- 如何通过 React 按其键返回对象内容(JSON 文件)
- 如何影响一个嵌套对象(React)中的一个键