Property 'toBeInTheDocument' does not exist on type 'Matchers<any>'
ReactjsTestingJestjsmocha.jsReactjs Problem Overview
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.
Reactjs Solutions
Solution 1 - Reactjs
Most of the answers here seem to address primarily Babel. With anything else like eslint, tslint etc. and pure Typescript 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
.
Solution 2 - Reactjs
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
Solution 3 - Reactjs
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.
Solution 4 - Reactjs
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';
Solution 5 - Reactjs
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
Solution 6 - Reactjs
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"
]
}
Solution 7 - Reactjs
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 addimport
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:
- The obvious, install
@testing-library/jest-dom
using:
npm install --save-dev @testing-library/jest-dom
- Add types
"types": ["node", "jest", "@testing-library/jest-dom"]
to tsconfig.json
similar as above.
- In your
jest.config.js
config add the below:
...
setupFilesAfterEnv: [
"@testing-library/jest-dom/extend-expect"
]
...
- Now, check your
roots: ["./src"],
path in yourjest.config.js
.
- Create a new file called
globals.d.ts
in that path - Make sure it is matching the
"included"
regex within yourtsconfig.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
withsupertest
for E2E, jest withreact-testing-library
for React testing and browsertestcafe
tests withreact-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 validtypes
declaration either intsconfig.json
or injest
config.
Solution 8 - Reactjs
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
These lines prepended to SetupTests.ts fixed it for me.
Solution 9 - Reactjs
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"
Solution 10 - Reactjs
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);
Solution 11 - Reactjs
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.
Solution 12 - Reactjs
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"
],
...
}