Search code examples
unit-testingjestjsreact-testing-libraryredux-toolkitvitest

How to spy on useAppDispatch() hook instance using redux-toolkit vitest


Since we can not use the hook useAppDispatch() within our test file, I wonder how can I spy on the returned instance.

import * as redux from "@/core/context/redux/store";

...

it("test",async ()=>{
    await waitFor(() => {
      wrapper = render(<MockForgeViewer />);
    });
    const spyDispatch = vi.spyOn(redux, "useAppDispatch");
    wrapper?.unmount();
    expect(spyDispatch).toHaveBeenCalledWith();
   
});

What I've just realized is that what this code is spying on the hook itself rather than the returned value (dispatch)

const dispatch = useAppDispatch();

indeed I wish to spy on dispatch to assert when a specific reducer has been called. Eg:

dispatch(resetStates());

Solution

  • it("test",async ()=>{
        await waitFor(() => {
          wrapper = render(<MockForgeViewer />);
        });
        const spyDispatch = vi.spyOn(redux, "useAppDispatch");
        wrapper?.unmount();
        expect(spyDispatch).toHaveBeenCalledWith();
       
    });
    

    What I've just realized is that what this code is spying on the hook itself rather than the returned value (dispatch)

    You should create a mock dispatch function to assert on, returned by your useAppDispatch spy.

    Example:

    const mockDispatch = vi.fn();
    const spyDispatch = vi.spyOn(redux, "useAppDispatch")
      .mockImplementation(() => mockDispatch);
    
    ...
    
    expect(mockDispatch).toHaveBeenCalledWith(resetStates());