在JSDOM中进行测试:jQuery在连续运行中未找到Enzyme Mocha中的元素

gee*_*sal 5 javascript mocha.js jsdom reactjs enzyme

我运行我的测试案例npm run test -- --watch,其中testmocha --require babel-polyfill --require babel-core/register --require ./test/withDom.js --require ./test/test_helper.js --recursive ./test命令来运行测试用例使用mocha

我的组件Jquery积极地用于操纵DOM和处理事件。

在我的第一次运行中,所有测试用例都运行良好。但是,一旦我修改了一些测试用例,观察者就会自动重新运行这些测试用例。在jquery无法找到使用选择以下的DOM元素。这很明显,因为DOM在我控制台登录wrapper.html()或时未修改页面body.innerHTML

如果您能解决这个问题,我将不胜感激。

这是代码

withDom.js

import { JSDOM } from 'jsdom';

const jsdom = new JSDOM('<!doctype html><html><body><div id="root"></div></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target),
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
global.requestAnimationFrame = function (callback) {
  return setTimeout(callback, 0);
};
global.cancelAnimationFrame = function (id) {
  clearTimeout(id);
};
copyProps(window, global);
Run Code Online (Sandbox Code Playgroud)

test_helper.js

import _$ from 'jquery';
import { mount, render, shallow, configure} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { expect } from 'chai';
import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from 'react-dom/test-utils';
import { MemoryRouter, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from '../src/reducers';

configure({ adapter: new Adapter() });
global.expect = expect;
global.mount = mount;
global.render = render;
global.shallow = shallow;
const $ = _$(window);

function renderComponent(ComponentClass, props = {}, state = {}) {
  const componentInstance =  ReactTestUtils.renderIntoDocument(
    <Provider store = {createStore(reducers, state)}>
      <MemoryRouter>
        <ComponentClass {...props} />
      </MemoryRouter>
    </Provider>
  );
  console.log('helper',componentInstance);
  return $(ReactDOM.findDOMNode(componentInstance));
}
export {renderComponent};
Run Code Online (Sandbox Code Playgroud)

example_test.js

import React from 'react';
import configureMockStore from 'redux-mock-store';
import { MemoryRouter, Link } from 'react-router-dom';
import thunk from 'redux-thunk';

import ItemList from '../../src/components/ItemList';
import RandomRater from '../../src/containers/RandomRater';
import { loadBooks } from '../../src/actions/index';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
let store, books, wrapper, params;

describe('<RandomRater/> Component',() => {

    beforeEach(()=>{
        store = mockStore();
        store.dispatch(loadBooks());
        books = store.getActions()[0].payload;
        params = { 'params': {'title' : 'Html & CSS Design & Build website' } };
    });

    it('renders <RandomRater/> containing <ItemList/> and <Link/>',()=>{     
        wrapper = mount(
                    <MemoryRouter>
                        <RandomRater store={store} books={books} match={params} />
                    </MemoryRouter>,
                    { attachTo: document.getElementById('root') }
                    );
        expect(wrapper).to.exist;
        expect(wrapper.contains(ItemList)).to.equal(true);
        expect(wrapper.contains(Link)).to.equal(true);
        expect(wrapper.text()).to.contains('Start Random Rating');
        expect(wrapper.text()).to.contains('Back');
    });

    it('<RandomRater/> random rates the books',()=>{
        //Below line is not modifying the dom after the first run. 
        wrapper.find('#btn-random-rate').simulate('click',{button:0});
        console.log('body',document.body.innerHTML);

        //This functions only runs on first run and not after that.
        setTimeout(()=>{
             expect(wrapper.text()).to.contains('Stop Random Rating')   
        },200);
        wrapper.detach();    
    });

    after(()=>{
       wrapper.detach(); 
    });
});
Run Code Online (Sandbox Code Playgroud)

注意:

如果我mocha每次都手动运行给定命令,则不会发生此问题。仅当我使用时才发生--watch

我已经提到了以下SO帖子,但是我的问题仍然没有解决。

更新:

这是带有完整代码的github回购。您可以修改测试用例RandomRater(请参见此处提供的RandomRater测试文件)并Rater重现问题。(请参见DOM模拟点击事件后的Start Rating按钮,RandomRater对于中的星星也是如此Rater