Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consider using the "jsdom" test environment

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.

like image 389
Rodrigo Avatar asked Sep 17 '21 17:09

Rodrigo


People also ask

What is jsdom environment?

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.

How to set Jest environment to jsdom?

To set up a JSDOM environment within Jest, start by creating a new Jest configuration file called jest. config. js . In this file, export an object whose testEnvironment property's value is "jsdom" .

How Jest tests use jsdom?

Jest uses jsdom to provide an environment that behaves much like a browser's DOM or document. Each test file gets a single instance of jsdom, and changes aren't reset between tests inside the file. It's a best practice to clean up between tests so that a test's output doesn't affect any other test.

Do I need to install jsdom?

jsdom is a pure JavaScript implementation of the DOM and browser APIs that runs in node. If you're not using Jest and you would like to run your tests in Node, then you must install jsdom yourself. There's also a package called global-jsdom which can be used to setup the global environment to simulate the browser APIs.

How do I run jest tests in jsdom?

Thanks to JSDOM, you can run your tests in Jest, which, as I have mentioned, can only run in Node. By using passing the value "jsdom" to Jest’s testEnvironment option, you can make it set up a global instance of JSDOM which you can use when running your tests.

How do I set up a global instance of jsdom?

By using passing the value "jsdom" to Jest’s testEnvironment option, you can make it set up a global instance of JSDOM which you can use when running your tests. Figure 2. The JavaScript environment within Node.

What is jsdom and how to use it?

With JSDOM you can emulate, manipulating the DOM and attaching event listeners to elements, for example. JSDOM JSDOM is an implementation of web standards written in purely in JavaScript which you can use in Node. To understand how JSDOM works, let’s use it to create an object that represents index.html and which we can use in Node.

Why can’t I use jest in node?

Given that Jest depends on Node-specific APIs and therefore only runs in Node, you can’t use Jest also. To be able to run your tests in Jest, instead of running your tests within the browser, you can bring browser APIs to Node by using JSDOM. You can think of JSDOM as an implementation of the browser environment which can run within Node.


Video Answer


2 Answers

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]

{
    "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

like image 134
Moistbobo Avatar answered Oct 17 '22 06:10

Moistbobo


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.

like image 25
Josh Kelley Avatar answered Oct 17 '22 05:10

Josh Kelley