react-testing-library why is toBeInTheDocument() not a function
Asked Answered
C

17

220

Here is my code for a tooltip that toggles the CSS property display: block on MouseOver and on Mouse Out display: none.

 it('should show and hide the message using onMouseOver and onMouseOut events respectively', () => {
    const { queryByTestId, queryByText } = render(
      <Tooltip id="test" message="test" />,
    )
    fireEvent.mouseOver(queryByTestId('tooltip'))
    expect(queryByText('test')).toBeInTheDocument()
    fireEvent.mouseOut(queryByTestId('tooltip'))
    expect(queryByText('test')).not.toBeInTheDocument()
    cleanup()
  })

I keep getting the error TypeError: expect(...).toBeInTheDocument is not a function

Has anyone got any ideas why this is happening? My other tests to render and snapshot the component all work as expected. As do the queryByText and queryByTestId.

Control answered 11/6, 2019 at 15:36 Comment(1)
I've posted a detailed answer for those who struggle using ts-jest without babel-jest and nothing works. I hope it will help: https://mcmap.net/q/120594/-property-39-tobeinthedocument-39-does-not-exist-on-type-39-matchers-lt-any-gt-39Thrasher
F
428

toBeInTheDocument is not part of RTL. You need to install jest-dom to enable it.

And then import it in your test files by:

import '@testing-library/jest-dom'
Forensic answered 12/6, 2019 at 8:37 Comment(6)
how do you import it, you could have provided the full answer here...Fishgig
@Fishgig Simply use import '@testing-library/jest-dom'Flowerlike
@Flowerlike , is it always like that?Pirzada
In Create React App import '@testing-library/jest-dom' will be in setupTests.ts. When upgrading from an older Create React App you need to create setupTests.ts. See github.com/facebook/create-react-app/blob/master/packages/…Vermeil
To clarify, it is not only in jest-dom. Other supporting libraries such as Jasmine support it too.Woolard
If you have tsconfig.json you can try to add next: "types": ["@testing-library/jest-dom"],Endodermis
J
162

As mentioned by Giorgio, you need to install jest-dom. Here is what worked for me:

(I was using typescript)

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

Then add an import to your setupTests.ts

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

Then in your jest.config.js you can load it via:

"setupFilesAfterEnv": [
    "<rootDir>/src/setupTests.ts"
  ]

Jessikajessup answered 22/2, 2020 at 12:0 Comment(4)
ESLint complains about jest.config.js syntax?Heterogenesis
I think you need to nest it inside module.exports = { ... }Protocol
Jest was working fine with the above solution, but VSCode was still complaining (Property 'toBeInTheDocument' does not exist on type...), so I had to install the types as well : yarn add @types/testing-library__jest-dom --devBegun
Fab313 comment works for me.Venial
S
15

When you do npm i @testing-library/react make sure there is a setupTests.js file with the following statement in it

import '@testing-library/jest-dom/extend-expect';
Saleable answered 22/8, 2020 at 7:41 Comment(1)
Are you sure? What happens at npm i that helps?Trapan
H
11

Some of the accepted answers were basically right but some may be slightly outdated: Some references that are good for now:

Here are the full things you need:

  1. in the project's <rootDir> (aka where package.json and jest.config.js are), make sure you have a file called jest.config.js so that Jest can automatically pick it up for configuration. The file is in JS but is structured similarly to a package.json.
  2. Make sure you input the following:
  module.exports = {
    testPathIgnorePatterns: ['<rootDir>/node_modules', '<rootDir>/dist'], // might want?
    moduleNameMapper: {
      '@components(.*)': '<rootDir>/src/components$1' // might want?
    },
    moduleDirectories: ['<rootDir>/node_modules', '<rootDir>/src'],
    setupFilesAfterEnv: ['<rootDir>/src/jest-setup.ts'] // this is the KEY
    // note it should be in the top level of the exported object.
  };
  1. Also, note that if you're using typescript you will need to make sure your jest-setup.ts file is compiled (so add it to src or to the list of items to compile in your tsconfig.json.

  2. At the top of jest-setup.ts/js (or whatever you want to name this entrypoint) file: add import '@testing-library/jest-dom';.

  3. You may also want to make sure it actually runs so put a console.log('hello, world!');. You also have the opportunity to add any global functions you'd like to have available in jest such as (global.fetch = jest.fn()).

  4. Now you actually have to install @testing-library/jest-dom: npm i -D @testing-library/jest-dom in the console.

With those steps you should be ready to use jest-dom:

Without TS: you still need:

  1. npm i -D @testing-library/jest-dom
  2. Creating a jest.config.js and adding to it a minimum of: module.exports = { setupFilesAfterEnv: ['<rootDir>/[path-to-file]/jest-setup.js'] }.
  3. Creating a [path-to-file]/jest-setup.js and adding to it: import '@testing-library/jest-dom';.

The jest-setup file is also a great place to configure tests like creating a special renderWithProvider( function or setting up global window functions.

Hydrocortisone answered 12/5, 2021 at 19:26 Comment(2)
adding it beneath /src/ when using typescript is a very important hint. I moved my setupTests.ts file due to some refactorings, which broke all tests thenBettyebettzel
This worked well, was the best explained answer with clear instructions. Thanks!Quartz
L
10

Having tried all of the advice in this post and it still not working for me, I'd like to offer an alternative solution:

Install jest-dom:

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

Then create a setupTests.js file in the src directory (this bit is important! I had it in the root dir and this did not work...). In here, put:

import '@testing-library/jest-dom'

(or require(...) if that's your preference).

This worked for me :)

Lap answered 15/10, 2021 at 14:39 Comment(0)
I
9

None of the answers worked for me because I made the silly mistake of typing toBeInDocument() instead of toBeInTheDocument(). Maybe someone else did the same mistake :)

Imaginal answered 3/2, 2022 at 14:14 Comment(1)
I couldn't figure it out at all after multiple hours, then I came across this comment and it fixed it. Thank you so much. Maybe if its such a common mistake "toBeInDocument" should be added as an alias.Crittenden
M
6

I had a hard time solving that problem so I believe it's important to note the followings if you're using CREATE REACT APP for your project:

  1. You DO NOT need a jest.config.js file to solve this, so if you have that you can delete it.
  2. You DO NOT need to change anything in package.json.
  3. You HAVE TO name your jest setup file setupTests.js and have it under the src folder. It WILL NOT work if your setup file is called jest.setup.js or jest-setup.js.
Mina answered 17/11, 2021 at 10:56 Comment(2)
This worked for me, thanks! There must be a way to change setupTests.js because probably some configuration key just defaults to this value.Bigmouth
Thanks, after 1h of trying..this was it! |setupTests.js seems to be not configurable in CRA. It is also one of the files generated by default (but probably everybody is deleting it from the start). create-react-app.dev/docs/running-testsOrose
K
5
  1. install required packages

    npm install --save-dev @testing-library/jest-dom eslint-plugin-jest-dom

  2. create jest-setup.js in the root folder of your project and add

    import '@testing-library/jest-dom'
    
  3. in jest.config.js

    setupFilesAfterEnv: ['<rootDir>/jest-setup.js']
    
  4. TypeScript only, add the following to the tsconfig.json file. Also, change .js extension to .ts.

    "include": ["./jest-setup.ts"]
    

toBeInTheDocument() and many similar functions are not part of the React-testing-library. It requires installing an additional package.

Krill answered 29/1, 2022 at 23:10 Comment(2)
Thanks! But why would anyone want to use typescript?Humane
Mr. Pudeyev, with respect, I believe that JavaScript is designed to perform how it is currently functioning, and TypeScript is developed to avoid quirky edges of JavaScript. We don't know JavaScript; we pretend we know---Getify. You should have deep knowledge of JavaScript to prevent them, so I personally use TypeScript to walk on the safety zone.Krill
A
3

For anyone out there that like is trying to run tests in Typescript with jest and is still getting the same error even after installing @testing-library/jest-dom and following all the other answers: you probably need to install the type definitions for jest-dom (here) with:

npm i @types/testing-library__jest-dom

or

yarn add @types/testing-library__jest-dom

You need to install them as real dependencies and not as devDependency.

Artery answered 14/7, 2022 at 14:28 Comment(0)
C
3

the problem already was solved, but i will comment a little tip here, you don't need to create a single file called setup just for this, you just need to specify the module of the jest-dom on the setupFilesAfterEnv option in your jest configuration file.

Like this:

setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
Cockneyism answered 8/2, 2023 at 12:46 Comment(0)
T
1

I was having this issue but for @testing-library/jasmine-dom rather than @testing-library/jest-dom.

The process of setup is just a tiny bit different with jasmine. You need to set up the environment in a before function in order for the matchers to be added. I think jest-dom will go ahead and add the matchers when you first import but Jasmine does not.

import { render, screen } from '@testing-library/react';
import MyComponent from './myComponent';
import JasmineDOM from '@testing-library/jasmine-dom';

describe("My Suite", function () {

  beforeAll(() => {
    jasmine.getEnv().addMatchers(JasmineDOM);
  })


  it('render my stuff', () => {
    const { getByText } = render(<MyComponent />);
    const ele = screen.getByText(/something/i);
    expect(ele).toBeInTheDocument();
  });
});
Towage answered 15/8, 2022 at 19:25 Comment(0)
A
1

If you are using react-script then follow the below steps

  1. Install @testing-library/jest-dom library if not done already using npm i @testing-library/jest-dom.
  2. Put import "@testing-library/jest-dom/extend-expect" in setUpTest.js

If you are using jest then import the library in jest.setup.js file.

Abana answered 26/12, 2022 at 10:30 Comment(0)
P
1

I didn't have to use @testing-library/jest-dom/extend-expect, just make sure you're on the latest version and it should already be imported as part of @testing-library/jest-dom when using the jest.setup.js file.

Polychromatic answered 24/4, 2023 at 19:41 Comment(0)
B
0

If you're using TS You could also add a test.d.ts file to your test directory and use a triple slash directive: ///<reference types='@testing-library/jest-dom'>

Ballard answered 22/11, 2022 at 22:47 Comment(0)
G
0

I fixed this by adding "./jest.setup.js" in the "include" array in tsconfig.json:

"include": ["next-env.d.ts", "/*.ts", "/.tsx", ".next/types/**/.ts", "./jest.setup.js"],

Glutton answered 31/8, 2023 at 1:32 Comment(0)
A
0

Besides all the answers mentioned in the comments above in my case replacing 'import' with 'require' helped. Even though all other inner files are imported via 'import' and other settings from the comments above were implemented too, they didn't helped until I've changed import

const { expect, describe, it } = require('@jest/globals');
Antepast answered 21/11, 2023 at 9:10 Comment(0)
S
-5

Instead of doing:

    expect(queryByText('test')).toBeInTheDocument()

you can find and test that it is in the document with just one line by using

    let element = getByText('test');

The test will fail if the element isn't found with the getBy call.

Spencer answered 2/6, 2020 at 20:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.