130

I'm trying to write tests for my simple React App that creates a UI for a dog Shelter using API etc. I have imported the modules shown below and ran the following command

npm install jest-dom react-testing-library --save-dev

However, I'm getting the toBeInTheDocument(); method underlined in red and the error message

"Property 'toBeInTheDocument' does not exist on type 'Matchers<any>'."
import "react-testing-library/cleanup-after-each";
import "jest-dom/extend-expect";

import * as React from "react";
import PetCard from "./PetCard";
import Pet from "./Pet";
import { render } from "react-testing-library";

const petMock = {
  id: "225c5957d7f450baec75a67ede427e9",
  name: "Fido",
  status: "available",
  kind: "dog",
  breed: "Labrador",
} as Pet;

describe("PetCard", () => {
  it("should render the name", () => {
    const { getByText } = render(<PetCard pet={petMock} />);
    expect(getByText("Fido")).toBeInTheDocument();
  });

});

Any advice on how I can resolve this is appreciated.

mangokitty
  • 1,759
  • 3
  • 12
  • 17
  • 1
    It sounds like it might be eslint complaining, have you tried changing the eslint environment? Try dropping this at the top of your test file `/* eslint-env jest */` – Adam Sep 09 '19 at 21:09
  • thank you this worked :) – mangokitty Sep 09 '19 at 21:15

18 Answers18

175

Most of the answers here seem to address primarily Babel. If you don't use Babel it's enough to add @testing-library/jest-dom to your types.

So a few quick steps:

Make sure you've got the library installed:

yarn add -D @testing-library/jest-dom

or

npm i @testing-library/jest-dom --save-dev

and then link it in your tsconfig.json:

"types": ["node", "jest", "@testing-library/jest-dom"],

Now we tackle Jest configuration. Rather than import it in every test file it is better to do it in the Jest config file (usually it's called jest.config.js):

setupFilesAfterEnv: [
   "<rootDir>/support/setupTests.js"
],

and then in the file setupTests.js:

import '@testing-library/jest-dom/extend-expect'

or use to require() if using pure JavaScript or different configuration.

The alternative (for TypeScript or if you don't like adding setupTests.js) is to add globals.d.ts (in my case to the project root directory) and add there the line above (import ...).

Note: Both solution work without setting esModuleInterop.

Note: If using TypeScript, add the typings with npm install @types/testing-library__jest-dom -D

Greg Wozniak
  • 5,209
  • 3
  • 26
  • 29
  • 1
    Was facing a problem with toBeVisible() not being found (TS2339: Property 'toBeVisible' does not exist on type 'JestMatchersShape, Matchers, any>>'). Importing jest-dom/extend-expect solved it. – x__x May 08 '20 at 14:17
  • 11
    Shouldn't the `"types": ["node", "jest", "@testing-library/jest-dom"]` be in the ts-configs? – Jjagwe Dennis Aug 11 '20 at 09:00
  • this isn't viable solely on `ts-jest` without `babel-jest` which requires an additional setup. Doing that you will get: `SyntaxError: Cannot use import statement outside a module` – Greg Wozniak Mar 18 '21 at 16:01
  • 2
    This solved it for me, thank you! – Awfulnaut Oct 01 '21 at 17:06
  • @JjagweDennis yeah, reworded – Greg Wozniak Oct 02 '21 at 11:10
  • Where does `setupFilesAfterEnv: [ "/support/setupTests.js" ],` go? – Jamie Hutber Feb 21 '22 at 10:33
  • 1
    @JamieHutber - top level as in the documentation https://jestjs.io/docs/configuration#setupfilesafterenv-array. – Greg Wozniak Feb 23 '22 at 13:03
  • 3
    This got almost everything working for me. Had to remove and readd the jest-dom types and restart VS Code then everything worked! i.e. I did a `yarn remove @testing-library/jest-dom` and a `yarn add @testing-library/jest-dom@XXX` where XXX was the version in my package.json I just removed. Looks like that also added `"@types/testing-library__jest-dom": "^5"` to my devDependencies which was likely the fix – Keego Jul 07 '22 at 22:56
  • 1
    For types, you have to add the type definitions: `yarn add -D @types/testing-library__jest-dom` – Tianhui Li Aug 05 '22 at 14:58
  • adding the "@testing-library/jest-dom" to the types array solved it for me. thanks – Itay Sidis Mar 09 '23 at 13:55
  • 1
    Was also facing a problem with `toBeVisible()` not being found. Turns out I was importing `expect` from `@jest/globals` instead of from `@testing-library/jest-dom` – Viktor Mar 30 '23 at 07:32
  • This works to run the tests without importing @testing-library/jest-dom in each test, but how do I make IntelliJ not complain that it can't resolve the reference? – sprut Aug 16 '23 at 16:22
  • warning: create-react-app is deprecated - in case you see this error while trying to set up a new project with create-react-app, which just happened to me after doing that and deleting my package-lock.json file. – Alexander Taylor Aug 21 '23 at 02:56
73

Please make sure that the correct types are installed in your project. i.e.

npm i -D @testing-library/jest-dom@^4.2.4

From my experience the Typescript types seem to be missing from version 5.x

Peter
  • 4,493
  • 6
  • 41
  • 64
  • 50
    You may also need to install the types: `@types/testing-library__jest-dom` – Jordan Stubblefield Aug 11 '20 at 17:32
  • 2
    [This issue](https://github.com/testing-library/jest-dom/issues/123) explains why they removed type definitions from the core. – shotasenga Dec 23 '20 at 01:57
  • I am using react native, is this also for me? – Dimitri Kopriwa May 08 '21 at 10:17
  • 1
    @DimitriKopriwa yes, if you are using Jest for your React Native application testing – Peter May 10 '21 at 12:37
  • 1
    I think "npm i -D @testing-library/jest-dom" would be better, it solved my problems :-) – Michiel Jun 29 '21 at 10:29
  • 1
    Same as @Michiel - no need to specify specifically version 4.2.4 anymore – fullStackChris Oct 11 '21 at 14:07
  • 3
    If you are still facing this issue after adding `@testing-library/jest-dom`. Ensure that in your test files you have imported `import '@testing-library/jest-dom';`. It is mentioned in [this comment](https://github.com/testing-library/jest-dom/issues/123#issuecomment-689689656) – Utsav Kapoor Nov 30 '21 at 01:55
  • `npm i -D @types/testing-library__jest-dom` It worked with v^5.16.4! – seongkuk han Jul 26 '22 at 01:02
  • I tried everything here, but I had another issue on top: I had an `import { describe, expect, test } from '@jest/globals';` statement after the `import '@testing-library/jest-dom';` which was giving me the wrong expect function. Make sure you don't have this extra import statement. – ahmadPH May 26 '23 at 05:07
27

For pnpm users (who might be wondering why this works out of the box with npm), it's because pnpm uses a semi-strict node_modules layout, which means only a few packages are hoisted to the top (ie. accessible via a simple import/require)

See the docs here: https://pnpm.io/blog/2020/10/17/node-modules-configuration-options-with-pnpm#the-default-setup

That's why if you are using pnpm the quick-fix that's needed currently is

pnpm add -D @types/testing-library__jest-dom

To make it a bit more robust one could edit .npmrc and figure out which hoisting setting to use.

PAStheLoD
  • 943
  • 12
  • 22
20

eslint overrides didn't help, but

import '@testing-library/jest-dom/extend-expect'

in the begging of the test file solved it.

I found this answer here and also in the jest setup file from the facebook's official react starter app. I hope it helps.

Evgeniya Manolova
  • 2,542
  • 27
  • 21
9

In my case it was enough to:

  • add to the package.json in devDependencies and install:
"@testing-library/jest-dom": "^5.11.9",
  • add to the .spec file:
import '@testing-library/jest-dom';
AlexxBoro
  • 329
  • 5
  • 3
8

The recent versions of @testing-library/jest-dom (e.g. 5.11.2) work out of the box, the issue for me was caused by cypress types conflicting with @types/chai used by @testing-library:

Since Chai and jQuery are namespaces (globals), incompatible versions will cause the package manager (yarn or npm) to nest and include multiple definitions and cause conflicts.

https://docs.cypress.io/guides/tooling/typescript-support.html#Configure-tsconfig-json

Solved by not including the cypress folder in the top-level TS config but instead adding cypress/tsconfig.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "baseUrl": "../node_modules",
    "types": ["cypress"]
  },
  "include": [
    "**/*.ts"
  ]
}
thisismydesign
  • 21,553
  • 9
  • 123
  • 126
8

The selected answer is usually correct if you are using babel-jest for traspilation.

For those who are still struggling due to the following errors:

  • Property 'toBeInTheDocument' does not exist on type 'JestMatchers<HTMLElement>'.
  • which leads to Cannot use import statement outside a module if you try to add import in jest.afterEnv file

Solving it with babel might lead to issues like Cannot use import statement outside a module due to the fact those two work differently. So if want to solve it purely using ts-jest (that means in your jest config you have line similar to):

transform: {
  "^.+\\.(ts|tsx)$": "ts-jest"
},

and nothing from the common answers worked then follow the steps below:

  1. The obvious, install @testing-library/jest-dom using:
npm install --save-dev @testing-library/jest-dom
  1. Add types
"types": ["node", "jest", "@testing-library/jest-dom"]

to tsconfig.json similar as above.

  1. In your jest.config.js config add the below:
...
setupFilesAfterEnv: [
  "@testing-library/jest-dom/extend-expect"
]
...
  1. Now, check your roots: ["./src"], path in your jest.config.js.
  • Create a new file called globals.d.ts in that path
  • Make sure it is matching the "included" regex within your tsconfig.json
  • Paste into globals.d.ts the following line.:
import "@testing-library/jest-dom/extend-expect"

Don't attach this line to your postEnv jest setup for ts-jest traspiler.

Run your tests and enjoy the result.

Side-notes:

  • My setup includes using jest for API testing, jest with supertest for E2E, jest with react-testing-library for React testing and browser testcafe tests with react-testing-library in the stack - and it all works now - so don't give up.
  • Make sure in your jest.config.js all the extensions are covered i.e. moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], especially if you are trying to run .tsx tests
  • If it happens that VSCode will stop highlighting in red toBeInTheDocument() during this process and your tests still throw the error you have likely missed the valid types declaration either in tsconfig.json or in jest config.
Greg Wozniak
  • 5,209
  • 3
  • 26
  • 29
5

As noted in the comment, it's your eslint configuration that needs to be changed. You should update your eslintrc file to include a configuration override for test files:

  ...
  overrides: [
    {
      files: [
        "**/*.test.js"
      ],
      env: {
        jest: true
      }
    }
  ]

Where "**/*.test.js" is a glob that matches the format of your test files.

Changing the eslintrc file ensures you don't have to add the eslint-env comment to the top of every test file.

See this answer as a reference: https://stackoverflow.com/a/49211283/1769777
Also see the jest environment configuration: https://eslint.org/docs/user-guide/configuring#specifying-environments

Adam
  • 4,445
  • 1
  • 31
  • 49
5
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';

These lines prepended to SetupTests.ts fixed it for me.

exaucae
  • 2,071
  • 1
  • 14
  • 24
  • This fixed it for me. I imported `@testing-library/jest-dom/extend-expect`, but I was missing `@testing-library/jest-dom`. In my case, the file was named `setup-test-env.ts`, but it's whatever you specify as the `setupFilesAfterEnv` export in `jest.config.js`. – ChrisCrossCrash Nov 16 '21 at 11:57
  • 1
    Glad it worked for you, @ChrisCrossCrash! :-) – exaucae Nov 17 '21 at 12:05
3

I dont know if someone need to read this. But i was stuck into this issue cuz i was re-importing some functions from jest. To avoid it, i remove this:

- import { describe, expect, it } from '@jest/globals';
ValRob
  • 2,584
  • 7
  • 32
  • 40
1

Please make sure you add: import "@testing-library/jest-dom/extend-expect" after: import { render } from "@testing-library/react"

import React from "react"
import { render } from "@testing-library/react"
import "@testing-library/jest-dom/extend-expect"
  • Can you explain how/why this would fix it? If you're importing `@testing-library/jest-dom` already then the rest of it is already imported – CWSites Apr 24 '23 at 18:21
1

This can happen if you are using different testing libraries together (e.g. Cypress and Jest). Both have expect with different matchers, which creates a conflict.

To fix it, you can try adding the following to tsconfig.json:

{
  ...,
  "exclude": [
    "**/*.spec.ts"
  ]
}

And the following to tsconfig.spec.json:

{
  "extends": "./tsconfig.json",
  "include": [
    "**/*.spec.ts"
  ],
  ...
}
Jöcker
  • 5,281
  • 2
  • 38
  • 44
1

I had this issue when importing types from @jest/globals as explained in the docs. testing-library/jest-dom in 5.0.1 moved their typed definitions in a separate package so that it works out of the box without any config. I needed to update testing-library/jest-dom and jest, not use any extra type library, not import any types, and it works out of the box.

setupTests.ts

import '@testing-library/jest-dom/extend-expect';

package.json

"@testing-library/jest-dom": "5.12.0"
"jest": "27.3.1"
thisismydesign
  • 21,553
  • 9
  • 123
  • 126
1

I was using only Jest and Cypress with NextJs. The issue kept occurring after trying everything until I added cypress.config.ts file to the list of exclude in my tsconfig.json file. Inside my tsconfig file, I did:

{
    "exclude": [..., "./cypress.config.ts"],
    ...
}

You can check this link for more info: https://github.com/cypress-io/cypress/issues/22059

Joshua
  • 46
  • 3
0

If you are getting this error while integrating Enzyme with Jest, make sure you use jest assertion methods.

In Enzyme documentation examples chai assertions are used. Instead of that we have to use jest assertions.

Ex. Use

expect(wrapper.find(Foo)).toHaveLength(3);

instead of

expect(wrapper.find(Foo)).to.have.lengthOf(3);
Yuvraj Patil
  • 7,944
  • 5
  • 56
  • 56
0

I messed with this for a couple of hours and read all the Q&A sites. Nothing worked, except for moving @testing-library/react and @testing-library/jest-dom out of devDependencies, and into dependencies.

I don't know why they're needed for production exactly, but it works.

Kraken
  • 5,043
  • 3
  • 25
  • 46
0

That's my solutions for this problem in my react project:

  1. install @types/testing-library__jest-dom.
npm i -D @types/testing-library__jest-dom
  1. according to @testing-library/jest-dom typescript usage, we need import '@testing-library/jest-dom' in jest-setup.ts and add setupFilesAfterEnv to jest.config.js
// In jest-setup.ts (or any other name)
import '@testing-library/jest-dom'

// In jest.config.js add setupFilesAfterEnv
setupFilesAfterEnv: ['<rootDir>/jest-setup.js']
  1. include jest-setup.ts in tsconfig.json
{
  "include": [
    "src/**/*",
    "./jest-setup.ts"
  ],
}
oxygen
  • 129
  • 1
  • 9
0

If you're using pnpm v7 or v8, Add this to your .npmrc:

public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=@types*

Then, run pnpm install

Reference: https://github.com/pnpm/pnpm/issues/4920#issuecomment-1226724790

ImBIOS
  • 630
  • 1
  • 9
  • 24