Jest mock react context

2020-07-02 11:50发布

I need some help understanding how one can test an application using React Context.

Here's my sample setup.

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

This is a simplified example. Imagine that there are more layers between App and MyComponent, hence the use of React Context.

And here's my test file for 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...?
}

The thing is, AppContext.Consumer is part of the implementation of MyComponent, so in this test I don't have direct access to it. How do I mock AppContext.Consumer so I am actually able to verify that clicking a button fires a function call?

I know that in theory I can test this by rendering MyComponent in my App, but I want to write a unit test for MyComponent only.

1条回答
我想做一个坏孩纸
2楼-- · 2020-07-02 12:50

You just render the context with your component.

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

See Mocking context with react-testing-library

查看更多
登录 后发表回答