jquery 不适用于 jsdom/enzyme

jquery doesn't work with jsdom/enzyme

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

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 + enzyme + 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);
    });
});

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

这是我 运行 mocha 的做法:

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

知道为什么 jquery 选择器在测试中找不到任何东西吗?它不应该是 mocha 问题,因为如果我更改为 jest

也会发生同样的问题

在 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

或另一种方式使用 jsdom-global 而不使用 test_helper.js 文件。

npm install --save-dev jsdom-global

然后:

import 'jsdom-global/register'; 

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

终于找到问题所在:

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

要进行完整 DOM 呈现并附加到当前文档:

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

其中 app 为空 div 在设置 jsdom 时可用:

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

我无法获取 to work. I did find 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);