You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest与React Testing Library中toBeInTheDocument()和toBeDefined()的区别及适用场景

toBeInTheDocument() vs toBeDefined():区别与适用场景

核心本质差异

  • 归属与依赖

    • toBeDefined() 是Jest原生内置断言,无需额外依赖即可使用。
    • toBeInTheDocument() 是@testing-library/jest-dom提供的扩展断言,必须安装并配置该包后才能使用,专门用于DOM元素的存在性校验。
  • 校验逻辑完全不同

    • toBeDefined() 仅检查变量/表达式的值不是undefined,与DOM无关。只要变量被声明过(哪怕赋值为null、0、''这类假值),断言都会通过。
    • toBeInTheDocument() 会验证目标DOM元素是否真实存在于当前渲染的DOM树中,确认元素已挂载且属于文档的一部分。

各自适用场景

什么时候用 toBeDefined()

  • 校验JS变量、函数返回值、组件props是否被正确初始化或传递:
    // 校验组件接收的props是否存在
    test('user prop should be defined', () => {
      const user = { name: 'Alice' };
      render(<UserProfile user={user} />);
      expect(user).toBeDefined();
    });
    
    // 校验工具函数的返回值不是undefined
    test('calculateTotal returns a valid value', () => {
      const result = calculateTotal([10, 20]);
      expect(result).toBeDefined();
    });
    
  • 注意:若需校验变量既不是undefined也不是null,建议改用toBeTruthy()或配合not.toBeNull()。

什么时候用 toBeInTheDocument()

  • 校验组件渲染后,目标DOM元素是否成功出现在页面上,这是React组件测试的高频场景:
    import { render, screen } from '@testing-library/react';
    
    test('renders login button correctly', () => {
      render(<LoginForm />);
      const loginButton = screen.getByRole('button', { name: /login/i });
      expect(loginButton).toBeInTheDocument();
    });
    
    test('shows error message on login failure', async () => {
      render(<LoginForm />);
      // 模拟登录失败操作
      await screen.findByText(/invalid credentials/i);
      expect(screen.getByText(/invalid credentials/i)).toBeInTheDocument();
    });
    
  • 也常用于校验元素是否被隐藏:配合queryBy*方法(找不到元素时返回null),做“元素不存在”的断言:
    test('hides loading spinner after data loads', async () => {
      render(<DataList />);
      await screen.findByRole('listitem');
      const spinner = screen.queryByRole('status');
      expect(spinner).not.toBeInTheDocument();
    });
    

常见误区

  • 不要用toBeDefined()校验DOM元素存在性:比如expect(screen.queryByText('hello')).toBeDefined(),即使元素不存在,queryBy*会返回null,而null属于已定义的值,断言会错误通过,完全达不到校验目的。
  • 不要用toBeInTheDocument()校验非DOM值:比如expect(user.name).toBeInTheDocument(),会直接报错,因为该方法仅接收DOM元素作为参数。

内容的提问来源于stack exchange,提问作者Vanmeeganathan P K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:55:23