John Glabb
John Glabb

Reputation: 1621

how properly mock multiple useSelector hooks

my component has multiple selectors:

import { useSelector } from 'react-redux'
...
const data1 = useSelector(xxxxx)
const data2 = useSelector(yyyyy)

How properly mock each in test file?

import { useSelector } from 'react-redux'
jest.mock('react-redux', () => ({
    useSelector: jest.fn()
}))
....
useSelector.mockImplementation(() => ({
   dataready: true
}))

which selector it's really mocking in this case?

Upvotes: 5

Views: 11620

Answers (3)

tony g
tony g

Reputation: 412

Don't mock the selector. You want to test the integration between Redux and React components, not the Redux implementation of selectors. If you use react-testing-library it's pretty simple to hijack the render() method and implement your store using a Redux Provider component. Here are the docs for setting up a reusable render function.

Here's your test re-written with the user in mind:

import { renderWithProviders } from '../../test-utils' // <-- Hijacked render

// Explanation of behavior
it('displays data when ready', { 
  renderWithProviders(<YourComponent />, { 
    preloadedState: {
      someSlice: {
        dataready: true // <-- Pass data for selector in store slice
      }
    }
  })

  // Check that something shows based on selector
  expect(screen.getByTestId('some-testId')).toBeInTheDocument()
})

Upvotes: 4

Jeremy
Jeremy

Reputation: 1568

You'd want to do something like this, to get your spy, and then check on what it is called with and mockImplementation to prevent async if thats an issue for you, i'd suggest you provide state via the render function, rather than mock a selector implementation though.

import { useDispatch, useSelector } from 'react-redux';
const reactRedux = { useDispatch, useSelector };
const useDispatchMock = jest.spyOn(reactRedux, 'useDispatch');

Upvotes: 0

mohammadhossein
mohammadhossein

Reputation: 21

import * as redux from 'react-redux';
...
  beforeEach(() => {
    jest
      .spyOn(redux, 'useSelector')
      .mockReturnValueOnce(xxxx)
      .mockReturnValueOnce(yyyy);
  });

Upvotes: 2

Related Questions