#reactjs #testing #redux #jestjs #react-testing-library
#reactjs #тестирование #redux #jestjs #react-testing-library
Вопрос:
Вот моя базовая настройка React:
- У меня есть компонент класса React
- Который подключен к моему хранилищу Redux с помощью connect()
- Который запускает функцию во время componentDidMount
- и эта функция является той, к которой компонент имеет доступ через 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')
Я был бы признателен за любые отзывы о том, как заставить это работать или как я должен протестировать эту функциональность.