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

IT技术 javascript reactjs jestjs react-testing-library
2021-05-20 08:24:16

我对 JavaScript 测试完全陌生,并且正在使用新的代码库。我想编写一个测试来检查元素上的 className。我正在使用 Jest 和React 测试库下面我有一个测试,它将根据variantprops呈现一个按钮它还包含一个 className,我想测试一下。

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)解决这个问题

4个回答

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

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

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

如果您classNameMDN 中阅读更多 about 您会看到它返回应用于您的元素的所有类,以空格分隔,即:

<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 测试,我鼓励您加入频谱论坛

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

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

您需要了解react-testing-library背后的哲学,以了解您可以用它做什么以及您不能做什么;

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

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

因此,与其通过用户看不到的东西以及可以随时更改的东西来搜索元素,不如尝试使用用户可以看到的东西来搜索,例如文本、标签或在元素的生命周期中保持不变的东西像数据ID。

因此,要回答您的问题,不建议测试 classname,因此您不能使用react-testing-library 进行测试尝试使用其他测试库,例如Enzymereact-dom test utils

您可以使用 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