jquery 不适用于 jsdom/酶

IT技术 javascript jquery reactjs enzyme jsdom
2021-04-26 16:35:04

我有一个带有以下组件的最小测试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 元素

但是,如果我使用 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);
    });
});

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

这是我运行摩卡咖啡的方式:

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

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

3个回答

终于找到问题了:

mount(<SomeComponent />)默认情况下,Enzyme会进行完整的 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>');

需要先完成一些设置,然后才能在 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

我无法得到Phuong Nguyen 的工作答复我确实在酶文档中找到了相关页面基于该页面上的最后一个示例,我最终得到了类似的结果:

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);