Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

testing react-redux useSelector

I have a react application which uses react-redux, useSelector to get data from the store. The react component has

function PersonDataView() {
  const name= useSelector(state => state.data.name)
  const dob= useSelector(state => state.data.dob)
  const dispatch = useDispatch()
  const show= () => dispatch({type: 'SHOW'})
  const remove= () => dispatch({type: 'REMOVE'})
  return (
    <div>
      <h2>Person Details</h2>
     <div>
      <button onClick={show}>Show</button>
      <span aria-label="name">{name}</span>
      <span aria-label="dob">{dob}</span>
      <button onClick={remove}>Remove</button>
     </div>
   </div>
  )
}

I am using react-testing-library to test this component. Is there any API which makes testing these components easier for us. I know two ways of testing these: 1) I can mock the store using redux-mock-store and then wrap this component under provider component. 2) mock the useSelector method in jest

jest.mock('react-redux', () => ({
  useSelector: () => ({
  })
});

But the problem using jest mock is in case of multiple selector, all the useSelectors will return same mocked value. Using jest way of mocking, jest.fn().mockReturnValueOnce() doesn't look correct to me.

like image 372
Krishna Avatar asked Jan 31 '20 21:01

Krishna


People also ask

How do you test thunk actions?

We use store. getActions() to identify the actions that our thunk has dispatched when it was called. expectedActions is an array which holds the list of actions that the thunk should have called. We pass this to expect() and verify if the actions that the thunk has dispatched are the same as those we had anticipated.

How do you test a reducer?

Test a reducer Reducers are so simple to test as they are pure functions. We just need to call the reducer function and pass in a fake piece of state and an action and then check the new state slice returns.


Video Answer


1 Answers

I'd suggest different approach - extracting your selectors into separate file, as e.g. file selectors.js:

const nameSelector = state => state.data.name;
const dobSelector = state => state.data.dob;

Then in test, you could mock useSelector as below:

jest.mock('react-redux', () => ({
  useSelector: jest.fn().mockImplementation(selector => selector()),
}));

And mock selectors separately, like:

jest.mock('./selectors.js', () => ({
  nameSelector: jest.fn().mockReturnValue("myTestName"),
  dobSelector: jest.fn().mockReturnValue("myTestDob"),
}));
like image 179
Emzaw Avatar answered Oct 27 '22 20:10

Emzaw