helloJT
helloJT

Reputation: 3

mock useDispatch followed by .then() with jest inside functional component

My scenario is just one step ahead of this existing question in stackoverflow

I have dispatch fn but with .then() followed by.

Component:

const Testing = props => {
const [counterData, setCounterData] = useState(0)
const resData = useSelector(state => state.test)
const dispatch = useDispatch()
useEffect(() => {
    dispatch(fetchTestinData())
        .then(res => {
            console.log(res);
            setCounterData(prev => prev + 1)
        })
}, [])

return <div>
    Testing component
    <div>
        Result - {resData.title}
    </div>
    <div>
        Counter - {counterData}
    </div>
</div>

}

Test file:

// const mockDispatch = jest.fn().mockResolvedValueOnce({json : async () => []})
const mockDispatch = jest.fn().mockImplementation(() => 
Priomise.resolve({title:'tets'}))
jest.mock('react-redux', () => ({
    ...jest.requireActual('react-redux'),
    useDispatch: () => mockDispatch
}))

describe('<Testing />', function () {
    const getComponent = (state) => <Provider store={store}>
        <Testing />
    </Provider>

    it('testing success api', () => {
        // window.fetch = jest.fn().mockResolvedValueOnce({title: 'testing title'})
        render(getComponent())
        screen.debug()
        // expect(mockDispatch).toBeCalledTimes(1)
    })

})

if am using just jest.fn() getting same error as well as with mock implemntaion. Error screenshot

Something am missing in mock fn implementaion. Plase help. Searched a lot but no luck.

Upvotes: 0

Views: 2674

Answers (1)

lbsn
lbsn

Reputation: 2412

Apparently Jest docs are a bit misleading about the possibility to use previously defined variables in a mock module factory: that is just not possible.

So the solution to your issue is just to move your mockDispatch implementation inside the module factory:

jest.mock('react-redux',
  () => ({
    ...jest.requireActual('react-redux'),
    useDispatch: () => jest.fn().mockImplementation(() =>
      Promise.resolve({ title: 'test' }))
  })
)

Upvotes: 1

Related Questions