如何通过接近 React 测试库中的另一个元素来获取元素
How to get element by proximity to another element in React Testing Library
我一直在尝试使用 React Testing Library and following their guiding principles 编写一些测试,因为测试应该以用户使用它的方式测试应用程序组件。
我有一个组件,它呈现一个对象列表,每个对象都有几个字段,导致 DOM 像这样:
<div>
<h1>Fluffy</h1>
<h2>Cat</h2>
<span>3 years old</span>
</div>
<div>
<h1>Oscar</h1>
<h2>Cat</h2>
<span>2 years old</span>
</div>
<div>
<h1>Charlie</h1>
<h2>Dog</h2>
<span>3 years old</span>
</div>
我想断言每个对象都使用相关字段正确呈现,但我看不出如何使用 React 测试库来做到这一点。到目前为止我有:
it('renders the animal names, species, and ages', () => {
render(<MyAnimalsComponent />)
const fluffyName = screen.getByRole('heading', { name: 'Fluffy' })
expect(fluffyName).toBeInTheDocument()
// The problem here is that there are multiple headings with the name "Cat" (Fluffy and Oscar) and I have no way of checking that the one that is returned is actually the one for Fluffy.
const fluffySpecies = screen.getByRole('heading', { name: 'Cat' })
expect(fluffySpecies).toBeInTheDocument()
// Likewise, the age "3 years old" is rendered for both Fluffy and Charlie. How do I make sure I get the one that is rendered in the same container as Fluffy's name?
const fluffyAge = screen.getByText('3 years old')
expect(fluffyAge).toBeInTheDocument()
})
有没有什么方法可以使用 React 测试库中的查询方法来仅查找与另一个元素具有共同父元素的元素?或者获取元素的父元素然后仅查找作为该元素子元素的元素的方法?
在遵循 React Testing Library 的指导原则的情况下实现这一目标的最佳方法是什么?
解决此问题的一种方法是使用顶级 getByRole
和 getByText
方法并传入一个元素作为第一个参数以将查询限制为该元素。
对于我的示例,这涉及在一些包装元素上设置 role
属性,以便更容易地从语义上查找元素:
<div role="list">
<div role="listitem">
<h1>Fluffy</h1>
<h2>Cat</h2>
<span>3 years old</span>
</div>
<div role="listitem">
<h1>Oscar</h1>
<h2>Cat</h2>
<span>2 years old</span>
</div>
<div role="listitem">
<h1>Charlie</h1>
<h2>Dog</h2>
<span>3 years old</span>
</div>
</div>
然后在测试中,我找到了不同的列表项,然后对这些项执行查询:
import { render, screen, getByText, getByRole } from '@testing-library/react'
it('renders the animal names, species, and ages', () => {
render(<MyAnimalsComponent />)
const animals = screen.getAllByRole('listitem')
const fluffyName = getByRole(animals[0], 'heading', { name: 'Fluffy' })
expect(fluffyName).toBeInTheDocument()
const fluffySpecies = getByRole(animals[0], 'heading', { name: 'Cat' })
expect(fluffySpecies).toBeInTheDocument()
const fluffyAge = getByText(animals[0], '3 years old')
expect(fluffyAge).toBeInTheDocument()
})
更新: 同样的事情可以使用 within
方法完成,可以说更容易理解:
import { render, screen, within } from '@testing-library/react'
it('renders the animal names, species, and ages', () => {
render(<MyAnimalsComponent />)
const animals = screen.getAllByRole('listitem')
const fluffyName = within(animals[0]).getByRole('heading', { name: 'Fluffy' })
expect(fluffyName).toBeInTheDocument()
const fluffySpecies = within(animals[0]).getByRole('heading', { name: 'Cat' })
expect(fluffySpecies).toBeInTheDocument()
const fluffyAge = within(animals[0]).getByText('3 years old')
expect(fluffyAge).toBeInTheDocument()
})
我一直在尝试使用 React Testing Library and following their guiding principles 编写一些测试,因为测试应该以用户使用它的方式测试应用程序组件。
我有一个组件,它呈现一个对象列表,每个对象都有几个字段,导致 DOM 像这样:
<div>
<h1>Fluffy</h1>
<h2>Cat</h2>
<span>3 years old</span>
</div>
<div>
<h1>Oscar</h1>
<h2>Cat</h2>
<span>2 years old</span>
</div>
<div>
<h1>Charlie</h1>
<h2>Dog</h2>
<span>3 years old</span>
</div>
我想断言每个对象都使用相关字段正确呈现,但我看不出如何使用 React 测试库来做到这一点。到目前为止我有:
it('renders the animal names, species, and ages', () => {
render(<MyAnimalsComponent />)
const fluffyName = screen.getByRole('heading', { name: 'Fluffy' })
expect(fluffyName).toBeInTheDocument()
// The problem here is that there are multiple headings with the name "Cat" (Fluffy and Oscar) and I have no way of checking that the one that is returned is actually the one for Fluffy.
const fluffySpecies = screen.getByRole('heading', { name: 'Cat' })
expect(fluffySpecies).toBeInTheDocument()
// Likewise, the age "3 years old" is rendered for both Fluffy and Charlie. How do I make sure I get the one that is rendered in the same container as Fluffy's name?
const fluffyAge = screen.getByText('3 years old')
expect(fluffyAge).toBeInTheDocument()
})
有没有什么方法可以使用 React 测试库中的查询方法来仅查找与另一个元素具有共同父元素的元素?或者获取元素的父元素然后仅查找作为该元素子元素的元素的方法?
在遵循 React Testing Library 的指导原则的情况下实现这一目标的最佳方法是什么?
解决此问题的一种方法是使用顶级 getByRole
和 getByText
方法并传入一个元素作为第一个参数以将查询限制为该元素。
对于我的示例,这涉及在一些包装元素上设置 role
属性,以便更容易地从语义上查找元素:
<div role="list">
<div role="listitem">
<h1>Fluffy</h1>
<h2>Cat</h2>
<span>3 years old</span>
</div>
<div role="listitem">
<h1>Oscar</h1>
<h2>Cat</h2>
<span>2 years old</span>
</div>
<div role="listitem">
<h1>Charlie</h1>
<h2>Dog</h2>
<span>3 years old</span>
</div>
</div>
然后在测试中,我找到了不同的列表项,然后对这些项执行查询:
import { render, screen, getByText, getByRole } from '@testing-library/react'
it('renders the animal names, species, and ages', () => {
render(<MyAnimalsComponent />)
const animals = screen.getAllByRole('listitem')
const fluffyName = getByRole(animals[0], 'heading', { name: 'Fluffy' })
expect(fluffyName).toBeInTheDocument()
const fluffySpecies = getByRole(animals[0], 'heading', { name: 'Cat' })
expect(fluffySpecies).toBeInTheDocument()
const fluffyAge = getByText(animals[0], '3 years old')
expect(fluffyAge).toBeInTheDocument()
})
更新: 同样的事情可以使用 within
方法完成,可以说更容易理解:
import { render, screen, within } from '@testing-library/react'
it('renders the animal names, species, and ages', () => {
render(<MyAnimalsComponent />)
const animals = screen.getAllByRole('listitem')
const fluffyName = within(animals[0]).getByRole('heading', { name: 'Fluffy' })
expect(fluffyName).toBeInTheDocument()
const fluffySpecies = within(animals[0]).getByRole('heading', { name: 'Cat' })
expect(fluffySpecies).toBeInTheDocument()
const fluffyAge = within(animals[0]).getByText('3 years old')
expect(fluffyAge).toBeInTheDocument()
})