在 react-testing-library 中通过 id 查找元素

Find element by id in react-testing-library

我正在使用 react-testing-libarary 来测试我的 React 应用程序。出于某种原因,我需要能够通过 id 而不是 data-testid 找到元素。文档中没有实现这一点的方法。

有办法实现吗?

我将渲染输出为:

const dom = render(<App />);

我正在寻找符合以下条件的东西:

const input = dom.getElemenById('firstinput');
//or 
const input = dom.getById('firstinput');

看起来您有 DOM 节点本身作为 container。因此,您应该可以用它调用 .querySelector('#firstinput')

我找到了一种方法。

import App from './App';
import { render, queryByAttribute } from 'react-testing-library';

const getById = queryByAttribute.bind(null, 'id');

const dom = render(<App />);
const table = getById(dom.container, 'directory-table');

希望对您有所帮助。

有两种方法

  1. 只需使用container.getElementById('id')。最后,所有帮助者所做的就是在幕后进行这样的查询
  2. 如果您想要自定义查询,您可以编写自定义呈现。查看文档以获取更多信息 https://github.com/kentcdodds/react-testing-library#getbytestidtext-textmatch-htmlelement

最后一点,如果您可以避免通过 id 查找元素,那就更好了。

你可以在配置里用testIdAttribute设置。

configure({ testIdAttribute: 'id' })

https://testing-library.com/docs/dom-testing-library/api-configuration


设置有利也有弊。这样做的好处是可以设置一个id多次使用。 (测试 ID、营销分析、标签管理器等)您不必同时添加 ID 和 test-id。有利于代码的简洁

但请注意,您可能会不小心在同一页面的两个不同组件中设置相同的 ID。请记住为列表项的组件 ID 添加索引或标识。

我觉得 none 的答案确实给出了完整的解决方案,所以这里是:

const result = render(<SomeComponent />);
const someElement = result.container.querySelector('#some-id');

我的建议:停止添加和搜索 id,这总是需要花费很多时间和精力,因为您必须添加 id(有时是测试 id),然后找出查询元素的最佳方式。但即使您确实需要一个 ID,此工具也会通过显示查询屏幕上任何 DOM 元素的最佳方式来为您节省大量时间:Testing Playground

如果您使用 TypeScript,并希望获得非 null 结果,这里有一个方便的函数:

function getById<T extends Element>(container: HTMLElement, id: string): T {
  const element = container.querySelector<T>(`#${id}`);
  assert(element !== null, `Unable to find an element with ID #${id}.`)
  return element;
}

然后你可以像这样使用它:

import { render } from '@testing-library/react';

const { container } = render(<App />);
const myInputElement = getById<HTMLInputElement>(container, 'myInputElement');