Consider using the "jsdom" test environment
Asked Answered
S

4

92

I have this simple test:

import React from 'react'
import { render } from '@testing-library/react'

import Button from '.'

describe('Button', () => {
  it('renders button without crashing', () => {
    const label = 'test'

    render(<Button label={label} />)
  })
})

And I have a jest.config.json with this content

{
  "setupFilesAfterEnv": [
    "<rootDir>/lib/settings/setupTests.ts"
  ]
}

And on my setupTests.ts I have

import '@testing-library/jest-dom'

When I run npm run test (which just run jest), I got the following error:

The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.

Consider using the "jsdom" test environment.

What I am doing wrong? This used to work before an upgrade.

Scholl answered 17/9, 2021 at 17:40 Comment(0)
M
201

In your package.json, or jest.config.js/jest.config.ts file, change the value of the testEnvironment property to jsdom.

package.json

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

jest.config.[js|ts]

module.exports = {
    "testEnvironment": "jsdom"
}

Important note for jest >28

If you are using jest 28, you will need to install jest-environment-jsdom separately by either:

npm: npm i jest-environment-jsdom --save-dev

yarn: yarn add -D jest-environment-jsdom

Why?

By default, jest uses the node testEnvironment. This essentially makes any tests meant for a browser environment invalid.

jsdom is an implementation of a browser environment, which supports these types of UI tests.

For Jest version 28 and greater, jest-environment-jsdom was removed from the default jest installation to reduce package size.

Additional reading

jest testEnvironment documentation

Jest 28 breaking changes

Museology answered 17/9, 2021 at 19:15 Comment(4)
Your answer helped me. Thank you. However, what you provide as jest.config.[js|ts] is json format. To use that snippet, you have to change the file name to jest.config.json.Dover
@Dover made the js/ts version more explicitMuseology
Is @testing-library/jest-dom also required for jest tests in the browser? Or does that package just add extra assertions that jest-environment-jsdom doesn't have natively?Shiflett
@MichaelLynch I believe that is an optional package if you are using the testing-library suite, so it is not required to write basic jest tests. Your assessment on it adding additional assertions is correct.Museology
C
27

This can be solved on a per-test-file basis by adding a @jest-environment docblock to the beginning of your file. For example:

/** @jest-environment jsdom */
import React from 'react'
import { render } from '@testing-library/react'

import Button from '.'

describe('Button', () => {
  it('renders button without crashing', () => {
    const label = 'test'

    render(<Button label={label} />)
  })
})

If your project has a mix of UI and non-UI files, this is often preferable to changing the entire project by setting "testEnvironment": "jsdom" within your package.json or Jest config. By skipping initializing the JSDom environment for non-UI tests, Jest can run your tests faster. In fact, that's why Jest changed the default test environment in Jest 27.

Caddoan answered 23/3, 2022 at 20:23 Comment(3)
/** @jest-environment jsdom */ worked when place on top of file but didn't work when placed above a test method. Do you know why?Sunrise
@Sunrise - It can only be changed on a per-file basis, not per-method. See jestjs.io/docs/configuration#testenvironment-stringCaddoan
thanks you! great explanation, I need jsdom for angular component tests, but firebase firestore rules tests need the node environment to run properly. This lets me set the right environment for each file.Morrow
S
2

by default the value for testEnvironment is node which runs all test cases in node.js envioronment, but js-dom provides browser like enviornment. instead of adding jsdom value, you can even add file specific value like below which will work.

/**
 * @jest-environment jsdom
 */
// the above comment helps
test('use jsdom in this test file', () => {
  const element = document.createElement('div');
  expect(element).not.toBeNull();
});

We can even add test file specific environments, please refer this link.

https://jestjs.io/docs/configuration#testenvironment-string

Skinner answered 9/5, 2022 at 7:52 Comment(0)
M
1

Try this:

jest.config.[js|ts]

module.exports = {
    testEnvironment: 'jsdom',
}
Maebashi answered 2/2, 2023 at 6:49 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Lidless

© 2022 - 2024 — McMap. All rights reserved.