如何使用Jest和React测试库测试className

Gij*_*rts 15 javascript reactjs jestjs react-testing-library

我是JavaScript测试的新手,并且在新的代码库中工作。我想编写一个在元素上检查className的测试。我正在与Jest和React-Testing-Library合作。下面我有一个测试,将根据variant道具。它还包含一个className和。我想测试一下。

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

我试图在Google上搜索像Enzyme一样具有的属性,hasClass但找不到任何东西。有谁知道如何使用当前库(react-testing-library,Jest)解决此问题?

Gio*_*Gpx 33

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

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

因此,如果您想知道将什么类应用于该类,container.firstChild可以像这样进行container.firstChild.className

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

<div class="foo">     => className === 'foo'
<div class="foo bar"> => className === 'foo bar'
Run Code Online (Sandbox Code Playgroud)

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

expect(container.firstChild.classList.contains('foo')).toBe(true)
Run Code Online (Sandbox Code Playgroud)

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

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

然后测试变为:

expect(container.firstChild).toHaveClass('foo')
Run Code Online (Sandbox Code Playgroud)

还有很多类似的方便方法toHaveStyle可以帮助您。


附带说明一下,react-testing-library是一个正确的JavaScript测试实用程序。与其他库相比,它具有许多优势。如果您不熟悉JavaScript测试,建议您加入Spectrum论坛


jbm*_*rom 17

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

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


gle*_*hes 15

您可以使用 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') 
})
Run Code Online (Sandbox Code Playgroud)

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

import '@testing-library/jest-dom/extend-expect';
import 'jest-axe/extend-expect';
// etc
Run Code Online (Sandbox Code Playgroud)


Yaz*_*jar 15

你应该使用toHaveClassJest 的。无需添加更多逻辑。

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 use screen instead of container because container is not recommended as per Documentation 
    expect(screen.getByRole('button')).toHaveClass(add you className)
})
Run Code Online (Sandbox Code Playgroud)


kas*_*oyo 7

您需要了解react-testing-library背后的哲学,以了解您可以做什么和不能做什么。

react-testing-library的目标是使测试避免包括组件的实现细节,而专注于编写使您有信心使用的测试。

因此按类名查询元素不符合react-testing-library哲学,因为它包含实现细节,类名实际上是元素的实现细节,不是最终用户会看到的东西,并且随时可能在其中发生变化。元素的生命周期。因此,与其尝试按用户看不见的内容搜索元素,而且可以随时更改的内容,不如尝试使用用户可以看到的内容(例如文本,标签或在元素生命周期中保持不变的内容)进行搜索。数据ID。

因此,要回答您的问题,不建议您测试类名,因此您不能使用react-testing-library来做到这一点。尝试使用其他测试库,例如反应测试工具

  • 我之前已经在这里和react-testing-library的作者那里看到过这个答案。我一直不明白。根据定义,“classNames”是用户将看到的东西。他们处于用户体验的最前线。很高兴知道是否已将重要的类助手应用于某个元素,以便该元素变得可见。 (67认同)
  • 对我来说,用 data-testid 搞乱 prod cod 比使用 class 属性浏览渲染的代码更大。更不用说,如果您想检查第 3 方代码的渲染,您实际上别无选择。除非你想模拟一切。人们也在制作不做的视频。我认为这是伟大的哲学而不是实践方法的情况。 (4认同)
  • 除此之外,一些 css 库(例如语义 UI)通过查看其 CSS 类使 DOM 更具可读性。所以你有类似 &lt;div class="title"&gt; 或 &lt;div class="step"&gt; 等的东西。如果不按类查询,在使用语义用户界面时很难断言 (3认同)
  • @mrbinky3000,您可以测试元素中类的存在/不存在,这非常好,并且在与 [jest-dom](https://github.com/testing-library/jest-dom) 一起使用时得到 RTL 的良好支持。ant-pattern 是在测试中通过 className 来定位元素。 (3认同)
  • 如果您主要关心的是您的产品代码具有 data-testid,那么在捆绑过程中始终可以将其删除。例如:babel-plugin-jsx-remove-data-test-id (3认同)
  • @mrbinky3000 用户看不到类名。尽管在实践中,不测试实现细节并不总是可以测试某些东西。 (2认同)
  • 作者实际上意识到这些原则并不适用于所有用例(在我的例子中,它是在网络请求期间测试旋转器/加载器的存在),因此他们写道:“本着指导原则的精神,这是建议仅在其他查询不适用于您的用例后才使用此(data-testid)。使用 data-testid 属性与您的软件的使用方式不同,应尽可能避免。也就是说,它们要好得多而不是基于 DOM 结构或样式化 css 类名进行查询。"` 我想这取决于你! (2认同)

小智 5

您可以使用 jest DOM 中的 toHaveClass

it('renders textinput with optional classes', () => {
  const { container } = render(<TextArea {...props} className='class1' />)
  expect(container.children[1]).toHaveClass('class1')
})
Run Code Online (Sandbox Code Playgroud)

不要忘记像这样解构响应,{container}因为默认情况下,React 测试库将创建一个 div 并将该 div 附加到document.body,这就是您的 React 组件将被渲染的地方。如果您通过此选项提供自己的HTMLElement容器,它将不会document.body自动附加到。