如何在 react-testing-library 中测试第三方组件库

KHm*_*man 1 reactjs react-testing-library

我有一个 react 组件,它从另一个第三方库(例如:Ant 或 bootstrap )导入一个组件,现在我想测试这个组件的 onClick 行为。

但是getByTestId或者getByText比较困难,因为第三方库没有thiese属性或者有时候html标签里没有文字。如何获取第三方 dom 并使用 react-testing-library 对其进行测试?

PS:有人可能会说,我们不必测试 bootstrap 组件,因为这是他们的事,但这会降低我们的测试覆盖率。(例如:如果我们将许多回调函数 props 作为事件处理程序传递给 a bootstrap 组件,我们必须测试回调增加测试覆盖率)

小智 6

据我了解,React 测试库的开发目的是根据用户对渲染元素的体验来编写测试。对于第三方组件,这有时会很麻烦。

我认为可以采取以下几种方法:

  1. 查看 React 测试库备忘单,问问自己用户理解元素的主要方式。也许在这种情况下它是由元素的作用?即,您的第三方组件是否拥有指示该组件角色的 aria 属性?

示例:应用程序使用引导程序中的按钮

const App = () => {
  const [state, setState] = useState(0)

  const increase = () => {
    const newState = state + 1
    setState(newState)
  }

  const decrease = () => {
    const newState = state - 1
    setState(newState)
  }

  return (
  <div>
    <div className="App">
      <Button variant="primary" size="lg" onClick={increase}></Button>{' '}
      <Button variant="primary" size="lg" onClick={decrease}></Button>{' '}
    </div>
    <div className="number">
      {state}
    </div>
</div>
  )
}
Run Code Online (Sandbox Code Playgroud)

我故意没有为按钮提供文本,但我仍然可以找到这些按钮,这是测试:

it('buttons increase and decrease displayed value', () => {
     const component = render(<App/>)
     const buttons = component.getAllByRole('button')

    for (let i = 0; i < buttons.length; i++){
      fireEvent.click(buttons[i])
    }

    expect(component.findByText('0')).toBeTruthy()
})
Run Code Online (Sandbox Code Playgroud)

即使我无法设置 testId 或通过文本查找,我仍然可以收集起按钮作用的节点数组。从那里开始搜索数组以找到您需要的按钮。令我高兴的是,测试通过了,但这是一个愚蠢的测试,因为按钮有自己的逻辑,所以我应该将它们分成单独的测试:

it('increases and decreases button and displays accurate value', () => {
    const component = render(<App/>)
    const buttons = component.getAllByRole('button')

    fireEvent.click(buttons[0])

    expect(component.findByText('1')).toBeTruthy()
})
Run Code Online (Sandbox Code Playgroud)
  1. 如果需要,请考虑将第三方组件包装在 div 中,为该数据提供 data-testid,然后访问作为该 div 子节点的第一个、兄弟节点、最后一个子节点。我经常使用它来导航到第三方组件节点在 dom 中的位置:

    <div data-testid="test">
        <SomeComponent onChange={()=> {}}/>
    </div>
    
    Run Code Online (Sandbox Code Playgroud)

由于一些反应测试库查询返回一个 dom 节点,我们可以通过以下方式找到该组件:

const findBootstrapComp = component.getByTestId('test').firstChild
Run Code Online (Sandbox Code Playgroud)
  1. 我们应该尽可能避免什么,但是鉴于提供的查询可以访问什么,您的情况可能是允许的,您可以通过某些属性手动查询容器节点:

    const { container } = render()
    const button = container.querySelector('button')
    
    Run Code Online (Sandbox Code Playgroud)

长话短说,React 测试库提供了大量工具来查询您需要的内容。如果该第三方组件正在呈现,那么您可能会查询该元素的属性。以上只是个人经验,每个项目不一样。甚至可以考虑拉出这些回调,隔离它们,然后测试逻辑,因为您更关心它的声音中的逻辑。

另外,我同意你对 Boostrap 测试他们自己的组件的看法。不过,您实际上并不是要测试第三方组件,而是要测试您编写的某些功能或逻辑正在被第三方组件访问。或者,您可能想要拉取该元素的 css 并确认它在开发过程中的某个时刻没有切换。不管是什么,我希望以上内容能在某种程度上有所帮助。如果有的话,请使用第三方组件在测试文件中创建一个组件,并使用 debug() api 查看元素以查看您可以查询的内容。

有用的网址:

React 测试库备忘单

DOM导航

节点接口