【问题标题】:Jest mock react context开玩笑模拟反应上下文
【发布时间】:2019-06-14 23:32:08
【问题描述】:

我需要一些帮助来了解如何使用 React Context 测试应用程序。

这是我的示例设置。

context.js

import React from 'react'

export const AppContext = React.createContext()

App.js

import React from 'react'

import MyComponent from './MyComponent'
import {AppContext} from './context'

const App extends React.Component {

  state = {
    items: []
  }

  handleItemAdd = newItem => {
    const {items} = this.state
    items.push(newItem)
    this.setState(items)
  }

  render() {
    return (
      <AppContext.Provider value={{
        addItem: this.handleItemAdd
      }}>
        <MyComponent />
      </AppContext.Provider>
    )
  }
}

export default App

MyComponent.js

import React from 'react'

import {AppContext} from './context'

const MyComponent extends React.Component {    
  render() {
    return (
      <AppContext.Consumer>
        {addItem => 
          <button onClick={() => addItem('new item')}>
            Click me
          </button>
        }
      </AppContext.Consumer>
    )
  }
}

export default MyComponent

这是一个简化的示例。假设AppMyComponent 之间有更多层,因此使用React Context

这是我的 MyComponent 测试文件。

MyComponent.test.js

import React from 'react'
import {render, fireEvent} from 'react-testing-library'

test('component handles button click', () => {
  const {getByText} = render(
    <MyComponent />
  )
  const button = getByText('Click me')
  fireEvent.click(button)
  expect...?
}

问题是,AppContext.ConsumerMyComponent 实现的一部分,所以在这个测试中我无法直接访问它。如何模拟AppContext.Consumer,以便我能够验证单击按钮是否会触发函数调用?

我知道理论上我可以通过在我的App 中渲染MyComponent 来测试这个,但我只想为MyComponent 编写一个单元测试。

【问题讨论】:

  • 查看 react-testing-library 的文档:testing-library.com/docs/example-react-context
  • 感谢您向我指出示例。那么,在每个测试中手动将MyComponent 包装在AppContext.Provider 中是唯一的方法吗?
  • 看起来是这样的。酶的shallow() 允许在上下文中作为参数传递。但 react-testing-library 没有。
  • @skyboyer,Enzyme 的 shallow 绝不适用于上下文。

标签: reactjs unit-testing jestjs react-context react-testing-library


【解决方案1】:

你只需用你的组件渲染上下文。

const addItem = jest.fn()
render(
  <AppContext.Provider value={{ addItem }}>
    <MyComponent />
  </AppContext.Provider>
)

Mocking context with react-testing-library

【讨论】:

    【解决方案2】:

    我想使用@Giorgio 的解决方案添加一个完整的测试示例。 这里我们测试 MyComponent 是否被渲染,并且它的按钮会被点击一次。

    MyComponent.test.js

    import React from 'react'
    import { render, fireEvent } from 'react-testing-library'
    
    test('component handles button click', () => {
      const addItem = jest.fn()
      render(
        <AppContext.Provider value={{ addItem }}>
          <MyComponent />
        </AppContext.Provider>
      )
      fireEvent.click(screen.getByText(/click me/))
      expect(addItem).toHaveBeenCalledTimes(1)
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-22
      • 2020-03-02
      • 2023-03-08
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多