Как проверить, что функция Redux dispatch вызывается во время componentDidMount в компоненте класса React?

#reactjs #testing #redux #jestjs #react-testing-library

#reactjs #тестирование #redux #jestjs #react-testing-library

Вопрос:

Вот моя базовая настройка React:

  1. У меня есть компонент класса React
  2. Который подключен к моему хранилищу Redux с помощью connect()
  3. Который запускает функцию во время componentDidMount
  4. и эта функция является той, к которой компонент имеет доступ через mapDispatchToProps (неявно)

Я хочу проверить, что вышеприведенное более или менее работает, что конкретная функция в этом случае fetchComments вызывается в течение componentDidMount жизненного цикла даже моего компонента.

Вот соответствующий код компонента:

 class CommentContainer extends React.Component{
  componentDidMount(){
    this.props.fetchComments(this.props.resourceId)
  }

...

export default connect(mapStateToProps, { authorizeUser, addComment, fetchComments })(CommentContainer)
  

Для тестирования я перепробовал МНОГО разных подходов. Единственное, что я могу приступить к работе, — это не проверять, что fetchComments было вызвано (что, насколько я понимаю, было бы лучшим способом изолировать функциональность), а проверить, что хранилище обновляется определенным образом (что произойдет только при fetchComments вызове).).

Тест, который у меня есть, который работает:

 import { render } from '@testing-library/react'

...

it ('loads comments upon rendering', ()=> {
  const store = createStore(rootReducer, applyMiddleware(thunk)) //I've also tried mockStores, but that didn't seem to work well with the connect() method in the component
  expect(store.getState().comments.loadStatus).toBe(null)
  render(<Provider store={store}>
          <Router>
              <CommentContainer 
                relativePath={"/resources/:id"} 
                resourceId={1}
              />
            </Router>
          </Provider>
        )
  expect(store.getState().comments.loadStatus).not.toBe(null)
}
  

То, что я хотел бы сделать, это нечто большее, чем:

 const spy = jest.spyOn(store, "dispatch")
render(<Provider store={store}>
            <Router>
            <CommentContainer 
              relativePath={"/resources/:id"} 
              resourceId={1}
            />
          </Router>
        </Provider>
        )
expect(spy).toHaveBeenCalledWith(fetchComments)
  

Однако, когда я делаю это, тест завершается неудачей. Шпион вызывается дважды, и результат, который я получаю, таков:

 Expected: [Function fetchComments]
    Received
           1: [Function anonymous]
           2: [Function anonymous]
  

Я полагаю, это происходит потому, что под капотом store.dispatch передается анонимная функция с «работой» fetchComments , но не передается фактическая функция fetchComments . Это точно?

Я также пытался, среди прочего, создать фиктивную функцию fetchComments и передать ее в качестве prop напрямую CommentContainer , но эта prop, похоже, перезаписывается connect() методом и mapDispatchToProps

Еще одна вещь, которую я пробовал, это использовать Enzyme и shallow and mount вместо react-testing-library render , а затем использовать .props() метод для извлечения fetchComments из CommentContainer , но когда я это сделал, я получил сообщение об ошибке, что prop был «Доступен только для чтения», поэтому я не мог сделать что-то вроде jest.spyOn(wrapper.props, 'fetchComments')

Я был бы признателен за любые отзывы о том, как заставить это работать или как я должен протестировать эту функциональность.