【问题标题】:jquery doesn't work with jsdom/enzymejquery 不适用于 jsdom/enzyme
【发布时间】:2017-06-28 21:52:02
【问题描述】:

我有一个包含以下组件的最小测试反应应用程序:

import React from 'react';
import $ from 'jquery';

export default class App extends React.Component {
    componentDidMount() {
        console.log('componentDidMount', $('#helloDiv').length);
    }

    render() {
        return <div id='helloDiv'>
            Hello React!
                </div>;
    }
}

在浏览器 (Chrome) 中加载它时效果很好。 componentDidMount() 中的 console.log() 打印出 1 helloDiv element found

但是,如果我使用 mocha + 酶 + jsdom 运行测试,App 组件中的相同 console.log() 会打印出 0:

import React from 'react';
import { mount } from 'enzyme';
import { expect } from 'chai';
import App from '../src/client/app/first'

describe('first test', () => {
    it('should pass', () => {        
        const app = mount(<App />);
        expect(app.find('#helloDiv').length).to.eq(1);
    });
});

注意:我对这个单元测试没有问题,它通过了。真正的问题是,当 使用酶安装时,componentDidMount() 被调用,但其中的 console.log() 语句打印出 0,而不是 1

这是我运行 mocha 的方式:

mocha --require enzyme/withDom --compilers js:babel-core/register test/index.test.js

知道为什么 jquery 选择器在测试中没有找到任何东西吗?这不应该是 mocha 的问题,因为如果我改成 jest 也会出现同样的问题

【问题讨论】:

  • 考虑在 Node.Js 应用程序中使用 cheerio 而不是 jQuery。
  • @Mijago 感谢您的建议。但是就我而言,我没有太多选择,至少目前是这样。这是我正在处理的当前项目的简化版本,jquery 已在整个项目中使用
  • 也许app.find('#helloDiv') 搜索应用inside,但应用本身有id?您的 jQuery 版本搜索整个文档。
  • @Prinzhorn 抱歉,我认为我的测试有点误导。我对期望本身没有问题。问题是在挂载 组件时,调用了 componentDidMount(),但其中的 console.log() 打印出 0。我将更新问题以澄清这一点
  • 我想答案仍然适用。该组件实际上并未安装在任何 jQuery 可以找到它的文档中。它只存在于 ReactWrapper 酶内部?

标签: javascript jquery reactjs enzyme jsdom


【解决方案1】:

我无法让Phuong Nguyen's answer 工作。我确实找到了the relevant page in the enzyme docs。根据该页面上的最后一个示例,我最终得到了类似的结果:

const div = global.document.createElement('div');
global.document.body.appendChild(graphDiv);
const wrapper = mount(<SomeComponent />, { attachTo: div });  // same as the other answer
// clean up after ourselves
wrapper.detach();
global.document.body.removeChild(div);

【讨论】:

  • 好像没有定义graphDiv。也许graphDiv 应该替换为div。对吗?
【解决方案2】:

终于找到问题了:

Enzyme mount(&lt;SomeComponent /&gt;) 默认情况下会进行完整的 DOM 渲染,但不会将渲染的组件插入到当前文档 (JSDom) 中。这就是为什么 jQuery 在当前文档中找不到任何元素的原因

要进行完整的 DOM 渲染并附加到当前文档:

mount(<SomeComponent />, { attachTo: document.getElementById('app') });

app 是设置 jsdom 时可用的空 div:

global.document = jsdom('<html><head></head><body><div id="app" /></body></html>');

【讨论】:

  • 我也有类似的问题。您的回答部分解决了它。但问题是我正在通过npm run test -- --watch 运行我的测试用例,其中testmocha --require babel-polyfill --require babel-core/register --require ./test/withDom.js --require ./test/test_helper.js --recursive ./test 运行测试用例的命令。所以,在第一次运行时,一切都运行良好,但是一旦我修改了一些测试用例并且观察者自动重新运行测试用例,你提到的问题就会再次出现。如果您能解决这个问题,我将不胜感激。
【解决方案3】:

需要先完成一些设置,然后才能在 node-env 中使用 jquery 进行 jsdom。

如果有帮助,试试这个。

像这样创建一个测试帮助文件 -

test_helper.js

import _$ from 'jquery';
import jsdom from 'jsdom';
import chai, { expect } from 'chai';
import chaiJquery from 'chai-jquery';

global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = global.document.defaultView;
global.navigator = global.window.navigator;
const $ = _$(window);

chaiJquery(chai, chai.util, $);

export {expect};

运行时-

mocha --require enzyme/withDom --compilers js:babel-core/register --require test/test_helper.js test/index.test.js

或其他方式使用没有 test_helper.js 文件的 jsdom-global。

npm install --save-dev jsdom-global

然后:

import 'jsdom-global/register'; 

//at the top of file , even  , before importing react

【讨论】:

  • 不,我没有收到任何错误。 console.log() 的输出仍然是 0。我猜如果是 jquery 问题,它会抱怨 $ not found 等
  • 您的 test_helper 文件是否从您提供的目录中使用?在 test_helper.js 文件中放一些 console.log 看看是否引用正确
  • 抱歉回复晚了。我发现了这个问题。更多详情见我的回答
  • 问题肯定与 jsdom 有关。
猜你喜欢
  • 2017-06-25
  • 2015-11-13
  • 2019-12-10
  • 2021-10-23
  • 2016-10-14
  • 1970-01-01
  • 2012-08-01
  • 2021-06-22
  • 2011-08-21
相关资源
最近更新 更多