【问题标题】:How do you test for the non-existence of an element using jest and react-testing-library?你如何使用 jest 和 react-testing-library 测试元素的不存在?
【发布时间】:2019-03-17 21:34:02
【问题描述】:

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

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

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

【问题讨论】:

    标签: reactjs jestjs react-testing-library


    【解决方案1】:

    为我解决了(如果你想使用 getByTestId):

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

    【讨论】:

      【解决方案2】:
      const submitButton = screen.queryByText('submit')
      expect(submitButton).toBeNull() // it doesn't exist
      
      expect(submitButton).not.toBeNull() // it exist
      

      【讨论】:

        【解决方案3】:

        另一种解决方案:您也可以使用 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();
        }
        

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

          • 这很容易出错。错误抛出用于调试目的,而不是用于验证。
          【解决方案5】:

          来自DOM Testing-library Docs - Appearance and Disappearance

          断言元素不存在

          标准的getBy 方法在找不到元素时会抛出错误,所以 如果你想断言一个元素 not 存在于 DOM 中, 您可以改用queryBy API:

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

          queryAll API 版本返回匹配节点的数组。的长度 数组在元素被添加或删除后对断言很有用 DOM。

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

          not.toBeInTheDocument

          jest-dom 实用程序库提供 .toBeInTheDocument() 匹配器,可以用来断言一个元素是 在文档的正文中,或不在。这可能比断言更有意义 查询结果为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()
          

          【讨论】:

          • 我的坏人,谢谢。我使用了getByTestId 并得到了同样的错误。而且,我没有查看常见问题解答,抱歉。很棒的图书馆!你能修改你的答案以包括`.toBeNull();
          • 我相信上面的链接是指向react-testing-library docs
          • 新的文档站点几天前发布了。我应该使用更永久的链接。感谢@pbre 的更新!
          • 另一个方便的资源:@​​987654323@
          • queryByText 对于那些想要与 getByText 等效的人来说是空安全的
          【解决方案6】:

          使用queryBy / queryAllBy

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

          但是,等效方法 queryBy*queryAllBy* 会返回 null[]

          queryBy

          queryBy* 查询返回查询的第一个匹配节点,如果没有元素匹配,则返回 null。这对于断言不存在的元素很有用。如果找到多个匹配项,则会抛出此错误(改用 queryAllBy)。

          queryAllBy queryAllBy* 查询返回一个查询的所有匹配节点的数组,如果没有元素匹配,则返回一个空数组 ([])。

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

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

          【讨论】:

          • 这比公认的答案要好得多。这个 API 更新了吗?
          • 感谢您的客气话!这与accepted answer 的功能基本相同,所以我不认为它是一个较新的 API(但我可能是错的)。这个答案和接受的答案之间唯一真正的区别是,接受的答案说只有一种方法可以做到这一点(queryByTestId),而实际上有两套完整的方法,其中queryByTestId 是一个具体的例子。
          • 谢谢 我更喜欢这个而不是设置 test-ids
          • 感谢您的详细解释。这是一个如此微妙的差异,尽管在这里查看了他们的示例,但我没有看到它:github.com/testing-library/jest-dom#tobeinthedocument:face-palm:
          【解决方案7】:

          您可以使用 react-native-testing-library "getAllByType" 然后检查组件是否为空。优点是不用设置TestID,也可以配合第三方组件使用

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

          【讨论】:

          • 这种违反了测试中没有实现细节(如组件名称)的前提。
          【解决方案8】:

          您必须使用 queryByTestId 而不是 getByTestId。

          这是一个代码示例,我想测试具有“汽车”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();
            });
          });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-02-11
            • 2020-03-22
            • 2021-02-28
            • 1970-01-01
            • 1970-01-01
            • 2020-05-14
            • 2020-03-24
            相关资源
            最近更新 更多