45

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.

Akber Iqbal
  • 12,257
  • 11
  • 34
  • 52
dorriz
  • 919
  • 1
  • 8
  • 16
  • 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://stackoverflow.com/a/66708479/2170368 – Greg Woz Mar 19 '21 at 12:48

6 Answers6

66

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

Giorgio Polvara - Gpx
  • 12,268
  • 5
  • 53
  • 55
  • 17
    how do you import it, you could have provided the full answer here... – eugsun Jan 30 '20 at 23:40
  • 10
    @EugenSunic Simply use `import '@testing-library/jest-dom'` – Cog Jul 24 '20 at 00:01
  • @Cog , is it always like that? – Welp Mar 04 '21 at 11:09
  • 2
    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 https://github.com/facebook/create-react-app/blob/master/packages/cra-template-typescript/template/src/setupTests.ts – André Ricardo Apr 27 '21 at 10:05
60

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


Jafin
  • 3,135
  • 35
  • 48
  • ESLint complains about jest.config.js syntax? – Kevin Burton Jul 04 '20 at 06:53
  • I think you need to nest it inside `module.exports = { ... }` – skube Jul 27 '20 at 17:43
  • 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 --dev``` – Fab313 Feb 03 '21 at 11:14
7

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';

Akber Iqbal
  • 12,257
  • 11
  • 34
  • 52
5

If you don't already have jest-dom installed, you need to install it using the command below.

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

create a file in the root of your project folder and name it jest-setup.js. Your file should have the following content.

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

In your package.json, add the code below to your jest config;

"jest": {
    "setupFilesAfterEnv": ["<rootDir>/jest-setup.js"]
}
  • It's a good answer but also make sure: `moduleFileExtensions: ['ts', 'tsx', 'js']` in your Jest config contains `.tsx`. That was missing in my case – Greg Woz Mar 18 '21 at 15:26
1

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 that file: add import '@testing-library/jest-dom';.

  3. You may also want to make sure its captured so put a console.log('hello, world!');.

  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.

Zargold
  • 990
  • 8
  • 20
-4

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.

Jane
  • 75
  • 2
  • 9