I'm trying to learn how to use Jest/Enzyme, and am stuck on providing my unit test with with the context dispatch functions. The first state context seems to work but the second one for the dispatch function doesn't. I'm aware I can pass a second parameter to the shallow function with the context, but I've not been able to get it to work that way either.
Error:
FAIL src/components/SearchBar.test.js
SearchBar.jsx
× should show search bar (4 ms)
● SearchBar.jsx › should show search bar
TypeError: Cannot destructure property 'asyncReducer' of '(0 , _Provider.useCocktailDispatch)(...)' as it is undefined.
7 | const SearchBar = () => {
8 | const state = useCocktailState()
> 9 | const { asyncReducer, dispatch } = useCocktailDispatch()
| ^
10 | const [modalShow, setModalShow] = useState(false)
11 | const [searchTerm, setSearchTerm] = useState(state.searchTerm)
12 |
at SearchBar (src/components/SearchBar.jsx:9:13)
at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:829:32)
at renderElement (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:643:26)
at fn (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:707:46)
at withSetStateAllowed (node_modules/enzyme-adapter-utils/src/Utils.js:100:18)
at Object.render (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:707:20)
at new ShallowWrapper (node_modules/enzyme/src/ShallowWrapper.js:411:22)
at shallow (node_modules/enzyme/src/shallow.js:10:10)
at Object.<anonymous> (src/components/SearchBar.test.js:13:25)
SearchBar.test.js snippet:
Enzyme.configure({adapter: new Adapter()})
jest.mock('../state-provider/Provider')
describe('SearchBar.jsx', () => {
it('should show search bar', () => {
// shallow renders react component to memory instead of DOM
// it wraps component in wrapper to give us functions to examine component
const wrapper = shallow(<SearchBar />) // <- line where error occurs
const searchBar = wrapper.find('InputGroup FormControl') // searchBar also a wrapper
expect(searchBar.exists()).toBe(true)
})
})
Provider.js:
import React, { useContext, useReducer } from 'react'
import { asyncReducer, reducer, initialState } from './reducer';
export const StateContext = React.createContext();
export const DispatchContext = React.createContext();
export const useCocktailState = () => {
const context = useContext(StateContext)
if (context === undefined) {
throw new Error(`useCocktailState must be used within a Provider`);
}
return context;
}
export const useCocktailDispatch = () => {
const context = useContext(DispatchContext)
if (context === undefined) {
throw new Error(`useDispatch must be used within a Provier`);
}
return context;
}
const Provider = ({children}) => {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<DispatchContext.Provider value={{asyncReducer:asyncReducer(dispatch),dispatch}}>
<StateContext.Provider value={state}>
{children}
</StateContext.Provider>
</DispatchContext.Provider>
)
}
export default Provider
See full code here: https://github.com/robert-levy/cocktail-finder
CodePudding user response:
jest.mock('../state-provider/Provider', () => ({
useCocktailDispatch: () => ({
asyncReducer: //your implementation of mock method or jest.fn() for dummy one
dispatch: //your implementation of mock or jest.fn() for dummy one
})
}))