如何使用 jest 和 react-testing-library 测试元素是否存在?

How do you test for the non-existence of an element using jest and react-testing-library?

我有一个组件库,我正在为使用 Jest 和 react-testing-library 编写单元测试。基于某些道具或事件,我想验证某些元素没有被渲染。

getByTextgetByTestId 等在 react-testing-library 中抛出错误,如果在 expect 函数触发之前未找到导致测试失败的元素。

你如何使用 react-testing-library 测试 jest 中不存在的东西?

来自DOM Testing-library Docs - Appearance and Disappearance

Asserting elements are not present

The standard getBy methods throw an error when they can't find an element, so if you want to make an assertion that an element is not present in the DOM, you can use queryBy APIs instead:

const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

The queryAll APIs version return an array of matching nodes. The length of the array can be useful for assertions after elements are added or removed from the DOM.

const submitButtons = screen.queryAllByText('submit')
expect(submitButtons).toHaveLength(2) // expect 2 elements

not.toBeInTheDocument

The jest-dom utility library provides the .toBeInTheDocument() matcher, which can be used to assert that an element is in the body of the document, or not. This can be more meaningful than asserting a query result is null.

import '@testing-library/jest-dom/extend-expect'
// use `queryBy` to avoid throwing an error with `getBy`
const submitButton = screen.queryByText('submit')
expect(submitButton).not.toBeInTheDocument()

您必须使用 queryByTestId 而不是 getByTestId。

这是一个代码示例,我想在其中测试具有 "car" ID 的组件是否不存在。

 describe('And there is no car', () => {
  it('Should not display car mark', () => {
    const props = {
      ...defaultProps,
      base: null,
    }
    const { queryByTestId } = render(
      <IntlProvider locale="fr" messages={fr}>
        <CarContainer{...props} />
      </IntlProvider>,
    );
    expect(queryByTestId(/car/)).toBeNull();
  });
});

您可以使用 react-native-testing-library "getAllByType" 然后检查组件是否为 null。优点是不必设置 TestID,也应该与第三方组件一起工作

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });

使用queryBy / queryAllBy.

如您所说,getBy*getAllBy* 如果找不到任何内容,则会抛出错误。

然而,等效方法queryBy*queryAllBy*代替returnnull[]

queryBy

queryBy* queries return the first matching node for a query, and return null if no elements match. This is useful for asserting an element that is not present. This throws if more than one match is found (use queryAllBy instead).

queryAllBy queryAllBy* queries return an array of all matching nodes for a query, and return an empty array ([]) if no elements match.

https://testing-library.com/docs/dom-testing-library/api-queries#queryby

因此对于您提到的特定两个,您应该使用 queryByTextqueryByTestId,但它们适用于所有查询,而不仅仅是这两个。

getBy* 在找不到元素时会抛出错误,因此您可以检查一下

expect(() => getByText('your text')).toThrow('Unable to find an element');

另一种解决方案:您也可以使用 try/catch

expect.assertions(1)
try {
    // if the element is found, the following expect will fail the test
    expect(getByTestId('your-test-id')).not.toBeVisible();
} catch (error) {
    // otherwise, the expect will throw, and the following expect will pass the test
    expect(true).toBeTruthy();
}
const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

expect(submitButton).not.toBeNull() // it exist

对我有用(如果你想使用 getByTestId):

expect(() => getByTestId('time-label')).toThrow()

我最近为一个 jest cucumber 项目写了一个检查元素可见性的方法。

希望有用。

public async checknotVisibility(page:Page,location:string) :Promise<void> 
{
    const element = await page.waitForSelector(location);
    expect(element).not.toBe(location); 
}