react: "Missing React element for debugID" warning when testing components with Jest

Do you want to request a feature or report a bug?

Report a bug.

What is the current behavior?

When testing components, Warning: ReactComponentTreeDevtool: Missing React element for debugID 1 when building stack is shown when calling TestUtils.renderIntoDocument.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/reactjs/69z2wepo/).

https://github.com/angusfretwell/reproduce-debugid-warning (npm install && npm test).

What is the expected behavior?

According to #7187 this is an internal warning and shouldn’t be displayed.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

  • react@15.2.1
  • react-addons-test-utils@15.2.1
  • react-dom@15.2.1

I didn’t receive this warning on 15.2.0.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 11
  • Comments: 62 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Let’s keep it open until either fix gets in.

OK, I started looking into it in #7395. This is not a super high priority since it’s just an errant warning and it doesn’t fail your tests. Still, we’d like to get it fixed of course.

Oh, I see what is happening here now.

Here is how Jest works in open source:

  • We call jest.resetModuleRegistry() implicitly in every beforeEach call. When doing require('React') (or import) on the top-level and then require('React') inside of a call to it), they will be fresh copies both times. I suspect the debug module is freshly required from an old version of React which will then go and require new versions of modules it requires itself.

At Facebook here is how Jest works:

  • We explicitly call jest.resetModuleRegistry() in beforeEach. Not every test does this, but every test should and I’ve been hoping to turn the open source behavior on internally as well.
  • We use top-level requires but we inline them. const React = require('React') will be removed and inlined into the code. Together with the module registry reset, this works pretty well and every call to it is completely isolated. Previously, the way we required modules in our tests internally was always quite the mess.

What we do at FB is what I’d recommend most people to do however people in open source have decided they want to use ES2015 imports, even in tests and there is not much I can do to stop them. That way they might end up with this confused state.

Jest sets the NODE_ENV to test – could we leverage this in React?

@jessy1092 What versions are you running?

I’m still seeing multiple instances of ERROR: 'Warning: ReactComponentTreeDevtool: Missing React element for debugID 17 when building stack'

react 15.3.0 react-dom 15.3.0

karma 1.1.2 karma-mocha 1.1.1 karma-mocha-reporter 2.0.5 mocha 2.5.3

Node 5.8.0 npm 3.8.2 Mac OS 10.11.6

Repro steps:

Clone, build and test mxstbr/react-boilerplate git clone https://github.com/mxstbr/react-boilerplate.git && cd react-boilerplate npm run setup npm test

All (78) tests pass. Errors seem to appear during <FeaturePage /> tests Testing FeaturePage only (npm run test -- --grep FeaturePage) does not produce errors.

ract-addons-test-utils is not included in the react-boilerplate project, but adding it does not remove the errors.

@gaearon I test on official release 15.3.0. The warning was gone. Thanks for hard work. 💯

As a super temporary fix you can put require('react/lib/ReactComponentTreeDevtool'); at the top level in your tests. I think this should fix the issue. Be sure to remove it when the next version is out 😄 . And only do this in tests.

Could this be some sort of a Jest issue (related to mocking?). In your example, if I put a log in the top level scope of ReactComponentTreeDevtool.js, I see it twice.

screen shot 2016-07-10 at 11 54 25 screen shot 2016-07-10 at 11 55 05

I’m not sure if this is normal.

I can also “fix” the issue by moving requires inside the test:

jest.unmock('../../components/HelloWorld');

describe('HelloWorld', () => {
  it('displays the message', () => {
    var React = require('react');
    var ReactDOM = require('react-dom');
    var TestUtils = require('react-addons-test-utils');
    var HelloWorld = require('../../components/HelloWorld').default;

    const helloWorld = TestUtils.renderIntoDocument(<div><HelloWorld /></div>);
    const helloWorldNode = ReactDOM.findDOMNode(helloWorld);
    expect(helloWorldNode.textContent).toEqual('Hello World');
  });
});

I would advise you to file an issue with Jest. It shouldn’t be executing our modules twice.

react@15.3.0 jest-cli@14.1.0

Can you try sticking "persistModuleRegistryBetweenSpecs": true into your config and whether that makes these warnings go away? We are gonna ship with this as a default in the next major of Jest and it is annoying that we haven’t done this before.

Jest actually resets all the modules in between calls to it to give even more isolation. So doing something like:

it('works', () => {
  const sum = require('sum');
  sum(1, 2);
});

it('works too', () => {
  const sum = require('sum');
  sum(1, 2);
});

both “sum” modules will actually be different instantiations of the module. So if you don’t want to change the option above, you can also inline all your requires manually:

it(‘works’, () => { const React = require(‘React’); expect(<div />).<matcher>; });

When we persist the module registry, both of them will be the same (=== is true). The downside is that you might have module local state between tests that is carried over. I think since people decided to predominantly use import statements in new code, this option makes no sense by default any more.

Face. Palm. Apparently I need more coffee.

Routing ERR to /dev/null works perfectly, as it should. Thanks again.

Along the same lines, you could also do something like npm run test 2>/dev/null if you are in a unix environment.