【问题标题】:React Mocha rendering, DOMException Wrong DocumentReact Mocha 渲染,DOMException Wrong Document
【发布时间】:2015-07-14 09:37:28
【问题描述】:

使用 React 13.2 并希望通过类似 gist 中所示的设置来测试生命周期。如果我不停止后续渲染(通过 shouldComponentUpdate 方法),那么任何事情都会导致渲染(在初始之后)以 DOMException Wrong Document 爆炸:

     DOMException: Wrong document
 at core.Node.insertBefore (D:\development\projects\fsm\node_modules\jsdom\lib\jsdom\level1\core.js:583:13)
 at core.Node.insertBefore (D:\development\projects\fsm\node_modules\jsdom\lib\jsdom\level2\events.js:326:32)
 at insertChildAt (D:\development\projects\fsm\node_modules\react\lib\DOMChildrenOperations.js:34:14)
 at Object.DOMChildrenOperations.processUpdates (D:\development\projects\fsm\node_modules\react\lib\DOMChildrenOpertions.js:106:11)

JSDOM 保释是因为父节点不是文档,并且它与插入的子节点不共享同一个所有者文档。是的。除非 React 在幕后做一些时髦的事情,否则拥有的文档怎么可能是全局文档。

很惊讶我没有看到更多人遇到类似问题?我的 Mocha 设置和渲染的 JSX 组件都没有什么奇怪的地方。加上初始渲染很顺利。

【问题讨论】:

标签: reactjs mocha.js jsdom reactjs-testutils


【解决方案1】:

节点 4 的更新

使用节点 4,我们可以使用最新的 jsdom 并以更好的方式解决此问题,例如使用testdom

这就是我在节点 4 上使用 mocha 测试 React 0.13 组件的方式:

import testDom from "testdom";
import { expect } from "chai";

testDom("<html><body></body></html>");
const React = require("react/addons");
const MyTestableComponent = require("../src/MyTestableComponent");
const ExecutionEnvironment = require("react/lib/ExecutionEnvironment");
ExecutionEnvironment.canUseDOM = true;

describe("MyTestableComponent", () => {
   it("works!", () => {
       const component = <MyTestableComponent />;
       expect(true).to.equal(true);
   })
})

注意我们应该require 而不是import React 和组件。


上一个答案

我可以按照 OP 对问题的评论来解决这个问题。

由于 React 将document 存储在一个内部变量中需要时,我们需要在再次需要它之前从require.cache 对象中删除 React:

var jsdom = require("jsdom").jsdom;
var React, TestUtils;

describe("Example", function() {

  beforeEach(function() {
    // remove react from the require cache
    for (var key in require.cache) {
      if (key.match(/\/node_modules\/react\//)) {
        delete require.cache[key];
      }
    }

    // init the DOM
    global.document = jsdom("<html><head><script></script></head><body></body></html>");
    global.window = document.parentWindow;

    // require react again    
    React = require("react/addons");
    TestUtils = React.addons.TestUtils;

  });

  // my tests...

});

【讨论】:

  • 然而,我正在使用此设置进行性能降级重复测试:不确定afterEach 上是否有事情要做
  • 这似乎导致使用refs的组件出错:Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's render method). Try rendering this component inside of a new top-level component which will hold the ref.
  • 相当肯定 react/lib/ExecutionEnvironment 在 React 0.14.x 中消失了,并且此修复程序将无法继续工作。一般来说,最好避免进入任何模块的内部,因为它可能会在没有警告的情况下发生变化。为了解决这个问题,我安装了“exenv”模块,并在类似于上面的代码中使用它代替了“ExecutionEnvironment”。它实际上只是 ExecutionEnvironment 的副本,但由于它没有复杂的依赖关系,因此它似乎是一个非常好的长期解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-04-06
  • 2018-11-18
  • 1970-01-01
  • 2011-09-07
  • 2016-09-18
  • 1970-01-01
  • 2015-06-24
  • 1970-01-01
相关资源
最近更新 更多