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

toiithl6  于 2023-06-20  发布在  Jest
关注(0)|答案(8)|浏览(169)

我对JavaScript测试完全陌生,正在使用一个新的代码库。我想写一个测试,检查元素上的className。我正在使用Jest和 React Testing Library。下面我有一个基于variant prop渲染按钮的测试。它还包含一个className,我想测试一下。

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

我试着在谷歌上搜索一个属性,比如酶有hasClass,但我找不到任何东西。如何使用当前的库(React Testing Library 和Jest)解决这个问题?

o75abkj4

o75abkj41#

你可以通过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

4zcjmb1e

4zcjmb1e2#

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

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

ssgvzors3#

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

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

因此,通过classname查询元素与 react-testing-library 哲学不一致,因为它包含了实现细节。类名实际上是元素的实现细节,并不是最终用户将看到的东西,并且在元素的生命周期中随时都会发生更改。
因此,不要搜索用户看不到的元素,而是尝试使用用户可以看到的内容进行搜索,例如文本,标签或在元素的生命周期中保持不变的内容,如data-id。
所以为了回答你的问题,不建议测试classname,因此你不能用 react-testing-library 来做。尝试使用其他测试库,如Enzymereact-dom test utils

n3h0vuf2

n3h0vuf24#

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

xhv8bpkk5#

您应该使用Jest中的toHaveClass。不需要增加更多的逻辑。

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)
})
7eumitmz

7eumitmz6#

可以从jest DOM使用toHaveClass

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

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

gcxthw6b

gcxthw6b7#

it('check FAQ link is working or not', () => {
    const mockStore = configureStore({ reducer: Reducers });
    const { container } = render(
      <GraphqlProvider>
        <Provider store={mockStore}>
          <BrowserRouter>
            <FAQ />
          </BrowserRouter>
        </Provider>
      </GraphqlProvider>,
    );
    const faqLink = container.getElementsByClassName('breadcrumb-item active');
    expect(faqLink[0].textContent).toBe('FAQ /');
  });
});
gab6jxml

gab6jxml8#

// 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);
  });
});

相关问题