笑话模拟反应上下文

art*_*ras 9 unit-testing reactjs jestjs react-context react-testing-library

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

这是我的示例设置。

context.js

import React from 'react'

export const AppContext = React.createContext()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这是一个简化的示例。想象在App和之间有更多的层MyComponent,因此使用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...?
}
Run Code Online (Sandbox Code Playgroud)

事实是,它AppContext.Consumer是的实现的一部分MyComponent,因此在此测试中,我无法直接访问它。我该如何模拟,AppContext.Consumer以便实际上可以验证单击按钮会触发函数调用?

我知道从理论上讲我可以通过MyComponent在自己的渲染中进行测试App,但是我只想编写一个单元测试MyComponent

Gio*_*Gpx 22

您只需使用组件渲染上下文。

const addItem = jest.fn()
render(
  <AppContext.Provider value={{ addItem }}>
    <MyComponent />
  </ApppContext.Provider>
)
Run Code Online (Sandbox Code Playgroud)

请参阅使用react-testing-library模拟环境

  • 哇,这比我想象的要简单得多,非常感谢! (9认同)

fjp*_*urr 7

我想使用@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)
}
Run Code Online (Sandbox Code Playgroud)