[React Testing] Test componentDidCatch handler Error Boundaries

Posted answer1215

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[React Testing] Test componentDidCatch handler Error Boundaries相关的知识,希望对你有一定的参考价值。

Error boundary:

import React from react
import { reportError } from ./components/extra/api

export default class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props)
    this.state = { hasError: false }
  }

  static defaultProps = {
    fallback: <h1>Something went wrong.</h1>,
  }

  static getDerivedStateFromError(error) {
    return { hasError: true }
  }

  componentDidCatch(error, errorInfo) {
    console.log(error, errorInfo)
    reportError(error, errorInfo)
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback
    }

    return this.props.children
  }
}

 

What we want to test is ‘reportError‘ was called when error happens

Test:

import React from react
import { render, fireEvent } from @testing-library/react
import { ErrorBoundary } from ./error-boundary
import { reportError as mockReportError } from ./components/extra/api

function Bomb(shouldThrow) {
  if (shouldThrow) {
    throw new Error(Bomb)
  } else {
    return null
  }
}

jest.mock(./components/extra/api)

test(calls reportError and renders that there was a problem, () => {
  mockReportError.mockResolvedValueOnce({ success: true })
  const { rerender } = render(
    <ErrorBoundary>
      <Bomb />
    </ErrorBoundary>,
  )

  rerender(
    <ErrorBoundary>
      <Bomb shouldThrow={true} />
    </ErrorBoundary>,
  )

  const error = expect.any(Error)
  const errorInfo = { componentStack: expect.stringContaining(Bomb) }
  expect(mockReportError).toHaveBeenCalledWith(error, errorInfo)
  expect(mockReportError).toHaveBeenCalledTimes(1)
})

// Clearn the mock impl afterEach(()
=> { jest.clearAllMocks() })

 

Notice:

  const error = expect.any(Error)
  const errorInfo = { componentStack: expect.stringContaining(Bomb) }

Both uses ‘expect‘ static methods.

expect.any(): https://jestjs.io/docs/en/expect#expectanyconstructor

expect.stirngContiaining(): https://jestjs.io/docs/en/expect#expectstringcontainingstring

 

In the testin, we mock the whole ‘api‘ module with jest.fn(), just provide the mock implementation for ‘reportError‘:

mockReportError.mockResolvedValueOnce({ success: true })

 

Remember to claer the mock Implmentation after each test:

afterEach(() => {
  jest.clearAllMocks()
})

 

以上是关于[React Testing] Test componentDidCatch handler Error Boundaries的主要内容,如果未能解决你的问题,请参考以下文章

[React Testing] Test componentDidCatch handler Error Boundaries

[React Testing] Improve Test Confidence with the User Event Module

[React Testing] Use Generated Data in Tests with tests-data-bot to Improve Test Maintainability(代码片段

在 react-testing-library 中,渲染应该只调用一次吗?

如何使用 react-testing-library 测试锚的 href

在 react-testing-library 中按 Enter 提交表单不起作用