React测试库为什么没有toBeInTheDocument()函数?

197

这是我的工具提示代码,它会在鼠标悬停时切换CSS属性display: block,并在鼠标移开时切换为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()
  })

我一直收到一个错误,TypeError: expect(...).toBeInTheDocument不是一个函数

有人知道为什么会出现这种情况吗?我用于渲染和快照组件的其他测试都按预期工作。queryByText和queryByTestId也可以正常工作。


我已经发布了一份详细的答案,针对那些在不使用babel-jest时遇到困难的人们。希望它能有所帮助:https://dev59.com/tVMH5IYBdhLWcg3w3EZO#66708479 - Greg Wozniak
17个回答

390

toBeInTheDocument 不是 RTL 的一部分。您需要安装 jest-dom 才能启用它。

然后通过以下方式在您的测试文件中导入:

import '@testing-library/jest-dom'

40
如何导入它,你可以在这里提供完整的答案... - EugenSunic
40
请直接使用 import '@testing-library/jest-dom'。这行代码的作用是导入 Jest-DOM 库,以便在测试中使用它提供的 DOM 匹配器。 - Cog
@Cog,这总是这样吗? - Welp
8
在 Create React App 中,import '@testing-library/jest-dom' 将会在 setupTests.ts 文件中。如果你从旧版本的 Create React App 升级,需要新建一个 setupTests.ts 文件。参见 https://github.com/facebook/create-react-app/blob/master/packages/cra-template-typescript/template/src/setupTests.ts - André Ricardo
1
澄清一下,这不仅仅是在 Jest-dom 中。其他支持库,如 Jasmine 也支持它。 - TimewiseGamgee
如果你有 tsconfig.json 文件,你可以尝试添加以下内容: "types": ["@testing-library/jest-dom"] - Vlad Rose

157

正如Giorgio所述,您需要安装jest-dom。以下是适用于我的方法:

(我正在使用typescript)

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

然后在你的 setupTests.ts 文件中添加一个导入

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

然后在你的 jest.config.js 中,你可以通过以下方式加载它:

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


ESLint 抱怨 jest.config.js 语法有问题? - Kevin Burton
1
我认为你需要将它嵌套在 module.exports = { ... } 内部。 - skube
3
以上解决方案中 Jest 运行良好,但 VSCode 仍在抱怨(_属性“toBeInTheDocument”不存在于类型..._),因此我不得不安装类型:yarn add @types/testing-library__jest-dom --dev - Fab313
Fab313的评论对我来说有效。 - HansolLim

14
当你执行 npm i @testing-library/react 命令时,请确保有一个名为 setupTests.js 的文件,并在其中添加以下语句。
import '@testing-library/jest-dom/extend-expect';

你确定吗?npm i 做了什么来帮助呢? - conor909

11

其中一些被接受的答案基本正确,但有些可能稍微过时了:

以下是您需要的全部内容:

  1. 在项目的 <rootDir>(也就是 package.jsonjest.config.js 所在的地方),确保您有一个名为 jest.config.js 的文件,这样 Jest 就可以自动选取它来进行配置。该文件是 JS 文件,但其结构与 package.json 类似。
  2. 确保您输入以下内容:
  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. 还需要注意的是,如果你在使用 TypeScript,你需要确保你的 jest-setup.ts 文件被编译(因此将其添加到 src 或在你的 tsconfig.json 中将其列入编译列表中)。

  2. jest-setup.ts/js(或其他你想要命名的入口文件)文件的顶部:添加 import '@testing-library/jest-dom';

  3. 你可能还希望确保它实际运行了,所以加上一个 console.log('hello, world!');。你也有机会添加任何你想在 jest 中全局使用的函数,例如 (global.fetch = jest.fn())。

  4. 现在你需要安装 @testing-library/jest-dom: 在控制台中输入 npm i -D @testing-library/jest-dom

通过以上步骤,你现在可以开始使用 jest-dom:

对于不使用 TypeScript 的情况:

  1. 仍然需要执行:npm i -D @testing-library/jest-dom

  2. 创建一个 jest.config.js 文件,并将以下代码添加到其中:module.exports = { setupFilesAfterEnv: ['<rootDir>/[path-to-file]/jest-setup.js'] }

  3. 创建一个 [path-to-file]/jest-setup.js 文件,并将以下代码添加到其中:import '@testing-library/jest-dom';

jest-setup 文件也是配置测试的好地方,例如:创建特殊的 renderWithProvider( 函数或设置全局 window 函数。


1
在使用 TypeScript 时,在 /src/ 目录下添加文件非常重要。由于一些重构,我移动了我的 setupTests.ts 文件,这导致所有测试都失败了。 - EimerReis
这个方法很有效,是最清晰明了、指示明确的答案。谢谢! - hasin

10

在尝试了本帖子中所有建议并仍无法解决问题后,我想提供一种替代方案:

安装jest-dom:

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

然后在src目录中创建一个setupTests.js文件(这一点很重要!我把它放在根目录下,结果没有起作用......)。在这个文件中添加以下内容:

import '@testing-library/jest-dom'

(或者 require(...),如果这更符合您的偏好)。

这对我有用 :)


从根目录切换到src目录帮了我,谢谢! - Neil

7

对于我来说,这些答案都没有用,因为我犯了一个愚蠢的错误,输入toBeInDocument()而不是toBeInTheDocument()。也许其他人也会犯同样的错误 :)


6

我在解决这个问题时遇到了一些困难,因此如果你正在使用CREATE REACT APP进行项目开发,请注意以下几点:

  1. 不需要使用jest.config.js文件来解决这个问题,因此如果您有这个文件,可以将其删除。
  2. 不需要更改package.json中的任何内容。
  3. 必须将jest配置文件命名为setupTests.js并放在src文件夹下。如果您的配置文件名为jest.setup.jsjest-setup.js,它将无法正常工作

这个对我有用,谢谢!一定有办法来改变setupTests.js,因为可能某些配置键只会默认为这个值。 - Akos K
谢谢,在尝试了一个小时后...就是这样了! 在 CRA 中,setupTests.js 似乎无法配置。它也是默认生成的文件之一(但可能每个人都会从一开始就删除它)。 https://create-react-app.dev/docs/running-tests/ - undefined

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() 和许多类似的函数并不是 React-testing-library 的一部分。它需要安装一个额外的包。


1
谢谢!但是为什么有人想要使用TypeScript呢? - Victor Pudeyev
1
Pudeyev先生,恕我直言,我认为JavaScript的设计是为了执行它目前的功能,而TypeScript则是为了避免JavaScript的一些棘手问题。我们并不真正了解JavaScript;我们只是假装了解——Getify。要想避免这些问题,你应该对JavaScript有深入的了解,因此我个人使用TypeScript来走在安全区域。 - Esmaeil MIRZAEE

3
对于那些想要使用jest在Typescript中运行测试,即使安装了@testing-library/jest-dom并遵循了所有其他答案,仍然出现相同错误的人:你可能需要安装jest-dom的类型定义( 这里):

npm i @types/testing-library__jest-dom

或者

yarn add @types/testing-library__jest-dom

你需要将它们安装为真正的依赖项而不是devDependency。


3

这个问题已经解决了,但我想在这里给出一个小提示,你不需要为此创建一个名为setup的单独文件,只需要在jest配置文件的setupFilesAfterEnv选项中指定jest-dom模块即可。

像这样:

setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接