由于需要 DOM,使用 reactjs renderIntoDocument 进行测试保持失败

Test with reactjs renderIntoDocument keep failed due to required DOM

我是 reactJS 的新手,正在尝试学习如何使用它进行测试。我遇到了以下测试实用程序方法。但是我不断收到相同的错误 message:ReferenceError: document is not defined


renderIntoDocument

ReactComponent renderIntoDocument(
  ReactElement instance
)

将组件渲染到文档中的分离 DOM 节点中。此函数需要 DOM.

注意: 在导入 React 之前,您需要让 window、window.document 和 window.document.createElement 全局可用。否则 React 会认为它无法访问 DOM 并且像 setState 这样的方法将不起作用。


我知道缺少 DOM 失败的原因,但我如何插入 DOM 或要求它?


我的测试如下:

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

tl;博士; 你需要 jsdom + Mocha.


根据规范 ReactTestUtils#renderIntoDocument,

renderIntoDocument() 需要 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.

传统上,React 中的单元测试是使用 Jest 完成的,它显然包含 DOM 支持。 Mocha 没有。

要理解这一点,请考虑这个过于简化的类比,Jest = Mocha + jsdom.

jsdom 是在 JavaScript 中实现的,我们可以在不需要浏览器的情况下使用类似 DOM 的 API。这意味着我们不必为了测试而捕获浏览器,例如 Karma(这就是为什么它会在您使用 Karma 时起作用)。因此,我们可以 运行 在没有浏览器的环境中进行测试,例如在 Node 或持续集成环境中。


参考文献:

  1. 教程:Testing React on Jsdom
  2. 反应规范:ReactTestUtils#renderIntoDocument
  3. 信息:How to Jest
  4. 信息:react-testing-mocha-jsdom

您需要 DOM。幸运的是,jsdomify 可以很容易地将 DOM 附加到 Node 中的全局变量。

假设我们有一个简单的组件:

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

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

我们可以用 renderIntoDocument 测试一下。下面是一个使用磁带的例子:

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