测试使用jQuery&的React组件窗口对象 [英] Testing a React component that uses jQuery & window object
问题描述
我的React组件必须响应我正在使用jQuery的resize
事件,即:
My React component has to respond to resize
event, for which I am using jQuery, ie:
//...
componentDidMount: function() {
$(window).on("resize", function);
}
//..
但是,这会导致我的Jest测试出现问题,具体来说:
However, this causes issues with my Jest test, specifically:
- TypeError: Cannot read property 'on' of undefined
at RadiumEnhancer.React.createClass.componentDidMount (bundles/Opportunities/OpportunityPartial.jsx:21:14)
单步执行测试时,好像在笑话测试中定义了window,但是$(window)
似乎没有返回任何内容.
When stepping through the test it looks like window is defined in a jest test, but $(window)
doesn't appear to return anything.
给我的印象是Jest会检查所需模块(jQuery)的API来构造其模拟,但是如果我正确地理解了这个问题,那似乎就没有发生?
I was under the impression that Jest would examine the required module (jQuery)'s API to construct its mock, but if I'm understanding the problem correctly it seems like this isn't happening?
我可以通过不模拟jQuery来解决此问题,但是显然这并不是完全可取的.
I can get around this by not mocking jQuery, but obviously that isn't totally preferable.
推荐答案
这是使用jestjs
和enzyme
的单元测试解决方案:
Here is the unit test solution using jestjs
and 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%:
Unit test result with 100% coverage:
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
这篇关于测试使用jQuery&的React组件窗口对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!