ttr*_*rmw 6 javascript jquery unit-testing reactjs jestjs
我的 React 组件必须响应resize事件,我使用的是 jQuery,即:
//...
componentDidMount: function() {
$(window).on("resize", function);
}
//..
Run Code Online (Sandbox Code Playgroud)
但是,这会导致我的 Jest 测试出现问题,特别是:
- TypeError: Cannot read property 'on' of undefined
at RadiumEnhancer.React.createClass.componentDidMount (bundles/Opportunities/OpportunityPartial.jsx:21:14)
Run Code Online (Sandbox Code Playgroud)
在单步执行测试时,看起来 window 是在 jest 测试中定义的,但$(window)似乎没有返回任何内容。
我的印象是 Jest 会检查所需的模块 (jQuery) 的 API 来构建它的模拟,但是如果我正确理解了问题,这似乎不会发生?
我可以通过不嘲笑 jQuery 来解决这个问题,但显然这不是完全可取的。
jestjs这是使用和的单元测试解决方案enzyme:
index.tsx:
import React, { Component } from \'react\';\nimport $ from \'jquery\';\n\nclass SomeComponent extends Component {\n componentDidMount() {\n $(window).on(\'resize\', this.resizeEventHandler);\n }\n\n resizeEventHandler() {\n console.log(\'resize event handler\');\n }\n\n render() {\n return <div>some component</div>;\n }\n}\n\nexport default SomeComponent;\nRun Code Online (Sandbox Code Playgroud)\n\nindex.spec.tsx:
import React from \'react\';\nimport SomeComponent from \'./\';\nimport { shallow } from \'enzyme\';\nimport $ from \'jquery\';\n\njest.mock(\'jquery\', () => {\n const m$ = {\n on: jest.fn(),\n };\n return jest.fn(() => m$);\n});\n\ndescribe(\'36082197\', () => {\n afterEach(() => {\n jest.restoreAllMocks();\n jest.resetAllMocks();\n });\n it(\'should pass\', () => {\n const logSpy = jest.spyOn(console, \'log\');\n const eventHandlerMap = {};\n ($().on as jest.MockedFunction<any>).mockImplementation((event, handler) => {\n eventHandlerMap[event] = handler;\n });\n const wrapper = shallow(<SomeComponent></SomeComponent>);\n const instance = wrapper.instance();\n expect(wrapper.text()).toBe(\'some component\');\n expect($).toBeCalledWith(window);\n // tslint:disable-next-line: no-string-literal\n expect($(window).on).toBeCalledWith(\'resize\', instance[\'resizeEventHandler\']);\n eventHandlerMap[\'resize\']();\n expect(logSpy).toBeCalledWith(\'resize event handler\');\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\n100%覆盖率的单元测试结果:
\n\n PASS src/stackoverflow/36082197/index.spec.tsx (12.045s)\n 36082197\n \xe2\x9c\x93 should pass (18ms)\n\n console.log node_modules/jest-mock/build/index.js:860\n resize event handler\n\n-----------|----------|----------|----------|----------|-------------------|\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |\n-----------|----------|----------|----------|----------|-------------------|\nAll files | 100 | 100 | 100 | 100 | |\n index.tsx | 100 | 100 | 100 | 100 | |\n-----------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests: 1 passed, 1 total\nSnapshots: 0 total\nTime: 14.267s, estimated 15s\nRun Code Online (Sandbox Code Playgroud)\n\n源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/36082197
\n