How to properly mock useSelector hook to return correct values while testing?

Viewed 3800

I have a function that calls useSelector multiple times upon rendering. In mocking the selector I used:

jest.spyOn(Redux, 'useSelector').mockReturnValueOnce(data).mockReturnValueOnce(moreData);

This changes the order of how hooks are called in my component. I have also tried creating a mock store and sending that into rendered component in the test as such:

const state = { userGuid: 'testGuid', user };
const store = mockStore(state);
jest.spyOn(Redux, 'useSelector').mockImplementation(() => store.getState());
const { getByTestId } = wrappedRender(ProfileScreen, mockProps, { store });

But this wraps the data in an extra object which my component cannot de-structure.

As of now I cannot find any other way to mock the return values of multiple useSelector calls without changing the order of hooks called. Any help is appreciated.

1 Answers

Relying on mockReturnValueOnce calls multiple times is a no-go as the order might change. The code below will just return the stubbed state no matter how many times useSelector is being called.

  import * as redux from 'react-redux'

  const user = {
    id: 1,
    name: 'User',
  }

  const state = { user }

  jest
    .spyOn(redux, 'useSelector')
    .mockImplementation((callback) => callback(state))
Related