Test with reactjs renderIntoDocument keep failed due to required DOM
Asked Answered
I

2

13

I am new to reactJS and try to learn how to test with it. I have encouter the following testing util method. However i am keep getting the same error message:ReferenceError: document is not defined.


renderIntoDocument

ReactComponent renderIntoDocument(
  ReactElement instance
)

Render a component into a detached DOM node in the document. This function requires a DOM.

Note: You will need to have window, window.document and window.document.createElement globally available before you import React. Otherwise React will think it can't access the DOM and methods like setState won't work.


I know it the reason failing its missing the DOM, but how can i insert the DOM or require it?


My test below:

import expect from 'expect.js';
import React from 'react';
import Header from '../../components/header';
import {renderShallow} from './help';
import ReactAddOn from 'react/addons';

var TestUtils = ReactAddOn.addons.TestUtils;

describe('Test react', function() {
  let component;

  beforeEach(()=>{
    component = TestUtils.renderIntoDocument(<Header></Header>);
  });


  it('Test if the content been correclty render', function() {
    console.log(component);
  });
});
Ithunn answered 28/10, 2015 at 4:52 Comment(9)
Have you installed jest? Also paste your test and component code that reproduces the issue, please.Susurrate
@limelights using mocha and expect.js at the moment do i need jest to get it working?Ithunn
No, you don't but it was tagged with Jest.Susurrate
@limelights my bad i thought it will attract people attention with testing, you ever experience above testing error?Ithunn
No worries, just update your question, please :)Susurrate
Can you show how you are using renderIntoDocument and where exactly the error is coming from?Pulp
@DavinTryon sure i will edit my questionIthunn
@DavinTryon react 0.14, i have used karma with jasmine instead and it works fine now... but mocha still not working but prefer mocha it's much faster.Ithunn
React 0.14 has split the dom into react-dom and split each addOn into its own package. For example, TestUtlis are now in react-addons-test-utils. You might have some issues with dependencies.Pulp
L
13

tl;dr; You need jsdom + Mocha.


According to spec ReactTestUtils#renderIntoDocument,

renderIntoDocument() requires a DOM:

You will need to have window, window.document and window.document.createElement globally available before you import React. Otherwise React will think it can't access the DOM and methods like setState won't work.

Traditionally, Unit testing in React is done using Jest, which apparently contains DOM support. And Mocha doesn't.

To understand this, consider this overly simplify analogy, Jest = Mocha + jsdom.

jsdom is implemented in JavaScript, we can have a DOM-like API to work with without needing a browser. That means that we don’t have to capture a browser in order test, like Karma (which is why it works the moment you use Karma). Hence, we can run our tests in environments without browsers, like in Node or in continuous integration environments.


References:

  1. Tutorial: Testing React on Jsdom
  2. React Spec: ReactTestUtils#renderIntoDocument
  3. Information: How to Jest
  4. Information: react-testing-mocha-jsdom
Logorrhea answered 25/11, 2015 at 10:42 Comment(2)
Thank you this is correct answer, you either use jsdom + mocha, or jasmine + karmaIthunn
It should be stated that this is incorrect: "Jest = Mocha + jsdom". What the answerer is rephrasing is simply that Jest provides a virtual DOM, and Mocha does not, but there are many more ways that Mocha and Jest are quite different from one another.Joceline
I
2

You need a DOM. Fortunately, jsdomify makes it easy to attach a DOM to your globals in Node.

Suppose we have a simple component:

var React = require('react');
module.exports = React.createClass({
  displayName: 'Foo',

  componentDidMount: function() {
    console.log('componentDidMount called');
  },
  render: function() {
    return (
      <p>hello world</p>
    );
  }
});

We can test this with renderIntoDocument. Here's an example using tape:

var jsdomify = require('jsdomify').default;
// We don't want to require React until we've set up the DOM
// (see the jsdomify docs).
var React;

var test = require('tape');

test('Render a Foo component with full react lifecycle', function (t) {
  jsdomify.create();
  React = require('react');

  var Foo = require('../Foo.jsx');

  // Full render to trigger componentDidMount.
  var ReactTestUtils = require('react-addons-test-utils');
  var renderer = ReactTestUtils.renderIntoDocument(<Foo/>);
  var result = renderer.render();

  // Cleans up global variables inserted by jsdomify.create.
  jsdomify.destroy();

  t.equal(result.props.children, 'hello world');
  t.end();
});
Insulin answered 9/8, 2016 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.