Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enzyme Throws an error if the React Component requires jQuery

I'm trying to test a React Components behavior using Enzyme's describeWithDOM() and mount(). But when the component imports jQuery I get this error:

Error: jQuery requires a window with a document

I know Enzyme uses jsdom under the hood, and I always thought jsdom took care of the window and document. But I can't seem to find how to get these working together.

The test code looks like this:

import chai, {expect} from 'chai';
import Select from './Select';
import React, {createElement} from 'react';
import {describeWithDOM, mount} from 'enzyme';

describe('UI Select', () => {

  //more shallow tests here

  describeWithDOM('User Actions', () => {
    it('Toggles the .ui-options menu on button click', () => {
      const wrapper = mount(<Select {...baseProps} />);
      expect(wrapper.state().open).to.not.be.ok;
      wrapper.find('button').simulate('click');
      expect(wrapper.state().open).to.be.ok;
    });
  });
}

In the buttons onClick method a jquery function is called: $('#inputSelector').focus()

How can I let Enzyme and jsdom use jquery in the tests?

like image 620
Barry127 Avatar asked Feb 06 '16 00:02

Barry127


1 Answers

describeWithDOM has been removed in the current version of Enzyme, and instead it is recommended to explicitly initialize global.document and global.window before all of your tests as shown here. I don't use jQuery, but I think this should provide the "window with a document" it is looking for.

The initialization code that Enzyme's own tests use is available in its withDom.js file:

if (!global.document) {
  try {
    const jsdom = require('jsdom').jsdom; // could throw

    const exposedProperties = ['window', 'navigator', 'document'];

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

    global.navigator = {
      userAgent: 'node.js',
    };
  } catch (e) {
    // jsdom is not supported...
  }
}

They use Mocha's --require option to ensure it executes before any of the tests:

mocha --require withDom.js --compilers js:babel-core/register --recursive test/*.js --reporter dot

like image 176
Trevor Robinson Avatar answered Sep 28 '22 16:09

Trevor Robinson