酶测试使用全局 jQuery 对象的 Reactjs 组件

Enzyme testing Reactjs component that uses global jQuery object

我正在逐步将 Reactjs 集成到使用 HTML5 和 jQuery 构建的 Web 应用程序前端中。我的 React 组件使用全局 jQuery 对象(用于 AJAX 和一些动画),当加载 React 组件 javascript 时该对象可用。

现在,当我尝试 mount() 使用 Enzyme 测试此组件时,出现以下错误

 ReferenceError: jQuery is not defined

如何使 jQuery 对象可用于安装的组件?

Testing a React component that uses jQuery & window object 是一个类似的问题,有 0 个答案...

如有必要,我愿意更新组件代码。

如有任何帮助,我们将不胜感激。

编辑

我的组件的示例代码

  import React from 'react';

  export default class MySimpleComponent extends React.Component {

     constructor(props) {
        super(props);
     }

     componentDidMount() {
        var add_btn = this.refs.btn_add;
        (function ($) {
           $(add_btn).click(function (ev) {
              ev.preventDefault();
              console.log('button was clicked');
           });
        })(jQuery);
     }

     render() {
        return (
           <div className="wrap">
              <form action="/">
                 <input type="text" name="myinput" value="" />
                 <button className="button" ref="btn_add">New Record</button>
              </form>
           </div>
        );
     }
  }

好的,您可以使用 jsdom 来做到这一点。您必须按照自述文件中的说明设置一些全局变量。也只需添加 global.jQuery = () => {};

var jsdom = require('jsdom').jsdom;

global.document = jsdom('');
global.jQuery = () => {};
global.window = document.defaultView;
Object.keys(document.defaultView).forEach((property) => {
  if (typeof global[property] === 'undefined') {
    global[property] = document.defaultView[property];
  }
});

global.navigator = {
  userAgent: 'node.js'
};

我还没有机会尝试以上内容。但是,我不建议将此作为可持续的解决方案。一个更好的方法是删除 jQuery。这是在没有它的情况下重构的组件。

  import React from 'react';

  export default class MySimpleComponent extends React.Component {

     constructor(props) {
        super(props);
     }

     clickHanlder(ev) {
       ev.preventDefault();
       console.log('button was clicked');
     }

     render() {
        return (
           <div className="wrap">
              <form action="/">
                 <input type="text" name="myinput" value="" />
                 <button className="button" onClick={this.clickHanlder}>New Record</button>
              </form>
           </div>
        );
     }
  }

如您所见,这并没有什么不同。您可以将事件处理程序直接附加到元素,可以这么说,对我而言,这使代码更易于阅读和查看操作的位置。