【问题标题】:How to test a className with the Jest and React testing library如何使用 Jest 和 React 测试库测试 className
【发布时间】:2019-04-22 17:13:03
【问题描述】:

我对 JavaScript 测试完全陌生,并且正在使用新的代码库。我想编写一个测试来检查元素上的类名。我正在与 Jest 和 React Testing Library 合作。下面我有一个测试,它将基于 variant 属性呈现一个按钮。它还包含一个类名,我想对其进行测试。

it('Renders with a className equal to the variant', () => {
    const { container } = render(<Button variant="default" />)
    expect(container.firstChild) // Check for className here
})

我试图用谷歌搜索像 Enzyme 那样的属性,hasClass,但我找不到任何东西。如何使用当前的库(React 测试库 和 Jest)解决这个问题?

【问题讨论】:

  • 你应该使用 Enzyme,因为这个原因,它的目的是与 jest 一起工作。 Jest 非常适合测试功能,Enzyme 适合组件测试和渲染。

标签: javascript reactjs jestjs react-testing-library


【解决方案1】:

简单地说,你应该使用 toHaveClass from Jest 无需添加更多逻辑

it('Renders with a className equal to the variant', () => {
    const { container } = render(<Button variant="default" />)
    expect(container.firstChild).toHaveClass(add you className);
//You Can Also You Screen Instead Of Using Container Container Not Recommended To Use As Documentation Said
    expect(screen.getByRole('button')).toHaveClass(add you className)
})

【讨论】:

    【解决方案2】:
        // Link.react.test.js
    import React from 'react';
    import ShallowRenderer from 'react-test-renderer/shallow';
    import App from './../../src/App'
    describe('React', () => {
      it('className', () => {
        const renderer = new ShallowRenderer();
        renderer.render(<App />);
        const result = renderer.getRenderOutput();
        expect(result.props.className.split(' ').includes('welcome-framework')).toBe(true);
      });
    });
    

    【讨论】:

      【解决方案3】:

      您需要了解 react-testing-library 背后的理念,以了解您可以使用它做什么和不能使用它做什么;

      react-testing-library 背后的目标是让测试避免包含组件的实现细节,而是专注于编写测试,让您对其预期的目标充满信心。

      因此,按类名查询元素不符合 react-testing-library 理念,因为它包含实现细节。类名是元素的实际实现细节,不是最终用户会看到的,并且在元素的生命周期中随时会发生变化。

      所以不要通过用户看不到的东西来搜索元素,并且可以随时更改的东西,只需尝试使用用户可以看到的东西来搜索,例如文本、标签或在生命周期中保持不变的东西像 data-id 这样的元素。

      因此,为了回答您的问题,不建议测试类名,因此您无法使用 react-testing-library 进行测试。尝试使用其他测试库,例如 Enzymereact-dom test utils

      【讨论】:

      • 我在这里和 react-testing-library 的作者那里看到过这个答案。我一直不明白。根据定义,“类名”是用户将看到的东西。他们处于用户体验的最前沿。很高兴知道一个重要的类助手是否已应用于一个元素,例如,该元素变得可见。
      • 除此之外,一些 CSS 库(如语义 UI)通过查看其 CSS 类使 DOM 更具可读性。所以你有类似
        等的东西。如果不按类查询,使用语义 ui 时很难断言
      • @mrbinky3000 您可以测试元素中类的存在/不存在,当与jest-dom 一起使用时,RTL 非常好并且得到很好的支持。 ant-pattern 是在测试中使用 className 来定位元素。
      • @mrbinky3000 用户看不到类名。尽管在实践中,不测试实现细节并不总是可以测试某些东西。
      • 用 data-testid 弄乱 prod cod 对我来说比使用 class 属性浏览呈现的代码更大。更不用说,如果您想检查 3rd 方代码的呈现,您真的别无选择。除非你想嘲笑一切。关于人们也制作视频不做。我认为这是一种伟大的哲学,但不是实用的方法。
      【解决方案4】:

      该库提供对普通 DOM 选择器的访问,因此我们也可以简单地这样做:

      it('Renders with a className equal to the variant', () => {
          const { container } = render(<Button variant="default" />)
          expect(container.getElementsByClassName('default').length).toBe(1);
      });
      

      【讨论】:

      • 应该是公认的答案。
      【解决方案5】:

      您可以使用 testing-library/jest-dom 自定义匹配器。

      @testing-library/jest-dom 库提供了一组自定义 jest 匹配器,您可以使用它们来扩展 jest。这些将使您的测试更具声明性,更易于阅读和维护。

      https://github.com/testing-library/jest-dom#tohaveclass

      it('Renders with a className equal to the variant', () => {
          const { container } = render(<Button variant="default" />)
      
          expect(container.firstChild).toHaveClass('class-you-are-testing') 
      })
      

      这可以在setupTest.js 文件中全局设置

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

      【讨论】:

        【解决方案6】:

        您可以使用 react-testing-library 轻松做到这一点。

        首先,您必须了解containergetByText 等的结果仅仅是DOM 节点。您可以像在浏览器中一样与它们进行交互。

        所以,如果你想知道 container.firstChild 应用了什么类,你可以像 container.firstChild.className 那样做。

        如果您在MDN 中阅读更多关于className 的信息,您会看到它返回所有应用于您的元素的类,以空格分隔,即:

        <div class="foo">     => className === 'foo'
        <div class="foo bar"> => className === 'foo bar'
        

        根据您的情况,这可能不是最佳解决方案。不用担心,您可以使用其他浏览器 API,例如 classList

        expect(container.firstChild.classList.contains('foo')).toBe(true)
        

        就是这样!无需学习仅适用于测试的新 API。就像在浏览器中一样。

        如果您经常检查某个类,您可以通过将jest-dom 添加到您的项目来简化测试。

        然后测试变成:

        expect(container.firstChild).toHaveClass('foo')
        

        还有很多其他方便的方法,例如 toHaveStyle,可以帮助您。


        顺便说一句,react-testing-library 是一个合适的 JavaScript 测试工具。与其他库相比,它具有许多优点。如果您不熟悉 JavaScript 测试,我鼓励您加入 spectrum forum

        【讨论】:

        • 嘿!我看到您使用的是toBeTrue,但由于某种原因,我得到了TypeError: expect(...).toBeTrue is not a function。我运行最新的 Jest 版本。 toHaveClass 工作正常!
        • 我的错是toBe(true) 我修好了。不过我使用toHaveClass,更简单
        • 对不起,我从未接受过这个答案。确实如此!
        • @GiorgioPolvara-Gpx 当库不支持 getByClass 方法时,我仍然认为这是一种 hacky 方式。
        • 您需要分两步完成,一个用于foo,另一个用于bar
        猜你喜欢
        相关资源
        最近更新 更多
        热门标签