Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React testing error: It looks like you called `mount()` without a global document being loaded

index.spec.js file:

import React from 'react';
import { mount } from 'enzyme';
import Header from './';
import { expect } from 'chai';

describe('header component', () => {
  let renderedOutput;
  beforeEach(() => {
    renderedOutput = mount(<Header />)
  })

  describe('initial state', () => {
    it('renders the header', () => {
      expect(renderedOutput).to.exist();
    });
    it('renders the header', () => {
      expect(renderedOutput).to.be.present();
    });
  })
});

Run the spec and it fails with: Error: It looks like you called mount() without a global document being loaded.

I've read something about jsdom but wasn't sure why to add that. anyone explain what I'm doing wrong?

like image 946
The worm Avatar asked Feb 23 '17 14:02

The worm


People also ask

Why should I unmount a component after every test?

This is why you unmount or cleanup the component after each test, because it’s almost a live app and one test will affect another test. Mount/render is typically used for integration testing and shallow is used for unit testing.

Should I use jest or enzyme to test my react application?

Sorry, something went wrong. For future readers with similar troubleshooting, if you're using enzyme to test React and need to test Full DOM Rendering, use Jest to run your tests and you'll be golden as it comes with jsdom baked in and properly set up. Sorry, something went wrong.

Why are Mount tests slower than shallow tests?

Not spending time painting anything to the UI makes your tests much faster. However mount tests are still much slower than shallow tests. This is why you unmount or cleanup the component after each test, because it’s almost a live app and one test will affect another test.

What is E to E testing in react?

Usually done with mounting or rendering a component. example: test if a child component can update context state in a parent. e to e testing: Stands for end to end. Usually a multi step test combining multiple unit and integration tests into one big test. Usually very little is mocked or stubbed.


2 Answers

Since enzyme's mount API requires a DOM, JSDOM is required in order to use mount if you are not already in a browser environment (ie, a Node environment).

For the best experience with enzyme, it is recommended that you load a document into the global scope before requiring React for the first time. It is very important that the below script gets run before React's code is run.

npm install --save-dev --save-exact jsdom jsdom-global

Then :

`import 'jsdom-global/register';` //at the top of file , even  , before importing react

More info here.

Alternative:

In your package.json, specify the test environment for jest as "jsdom" as follows:

  "jest": {
    "testEnvironment": "jsdom"
  }

I faced the same issue and it worked well for me.

like image 56
Peter Avatar answered Nov 10 '22 19:11

Peter


I would recommend you two things that will probably fix your issue, first of all, do the mount in each describe, the reason behind this is that you should make each test independent of each other, so unless you start to use Rewire in your beforeEach, it is better to start each test in a clean situation.

As another suggestion, maybe you have more tests, but in this case, since your are only testing that the component was mounted and exist you can use shallow instead of mount, and that will only mount the component in a shallow mode, which will be faster, but will not trigger every life-cycle event of react.

Your final code should look like the following

import React from 'react';
import { shallow } from 'enzyme';
import Header from './';
import { expect } from 'chai';

describe('header component', () => {
  describe('initial state', () => {
    it('renders the header', () => {
      const renderedOutput = shallow(<Header />)
      expect(renderedOutput).to.exist();
    });
    it('renders the header', () => {
      const renderedOutput = shallow(<Header />)
      expect(renderedOutput).to.be.present();
    });
  })
});

Let me know if it makes sense to you and more important, if it works.

Aditionally you may need to include the jsdom as you mention, see this related post here: Error: It looks like you called `mount()` without a global document being loaded

like image 20
rdarioduarte Avatar answered Nov 10 '22 19:11

rdarioduarte