Search code examples
react-testing-libraryreact-hooks-testing-library

React Testing Library merged with @testing-library/react-hooks, wrapper inconsistent in renderHook


With @testing-library/react-hooks I used to pass mocked store through initialProps just as mentioned in Advanced Hooks docs. Let's assume I have a code:

import configureMockStore from 'redux-mock-store'
import { Provider } from 'react-redux'

const initialState = {}
const customStore = configureMockStore(initialState)

// this wrapper is nicely reusable across all tests
const wrapper = ({ children, store = customStore }) =>
  <Provider store={ store }>
    {children}
  </Provider>

const useCustomHook = () => {
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch({ type: 'ACTION' })
  }, [])
}

test('should get dispatched action', () => {
  renderHook(useCustomHook, {
    wrapper: wrapper,
    initialProps: {
      store: customStore
    }
  })

  expect(customStore.getActions()).toEqual([{ type: 'ACTION }])
})

If I run this code with RTL before update (version 10.4.5) and @testing-library/react-hooks everything works as expected. But after these packages have merged, wrapper property in renderHooks function doesn't accept any other properties except children.

First iteration lead me to this solution:

renderHook(useCustomHook, {
  wrapper: ({ children }) => (
   <Provider store={ customStore }>{children}</Provider>
  )
})

...that's not as good in reusability as my previous wrapper. Is there any good solution of this problem?


Solution

  • The solution:

    const customWrapper = (store) => ({ children }) =>
      // this function is mentioned in question
      wrapper({
        children,
        store
      })
      
    test('Some test #1', () => {
      const mockedState = {}
      const mockedStore = configureMockStore(mockedState)
    
      const { result } = renderHook(() => useCustomHook(), {
        wrapper: customWrapper(mockedStore)
      })
    })