0

I'm creating a React application and use react-boilerplate as my base project. After getting my head around Redux, Sagas and reselect and got my first components running, I'd like to write the corresponding unit tests. But unfortunately I'm not able to get the test for the select statement with a corresponding selector to test correctly:

const selectDomain = () => (state) => state.get('myDomain');
const selectDomainMessage = () => createSelector(selectDomain(), (domain) => domain.get('message'));

function* send() {
  const message = yield select(selectDomainMessage());
  ...
  yield put(sentAction(message);
}

describe('send Saga', () => {
  const generator = send();

  it('should return select descriptor', () => {
    let expectedDescriptor = select(selectDomainMessage());
    let returnedDescriptor = generator.next().value;

    expect(returnedDescriptor).toEqual(expectedDescriptor);
  });
});

From my point of view, this test should work, but it fails with the (not really helpful) error message:

Expected Object({ @@redux-saga/IO: true, SELECT: Object({ selector: Function, args: [ ] }) }) to equal Object({ @@redux-saga/IO: true, SELECT: Object({ selector: Function, args: [ ] }) }).

To easier reproduce the problem I created a JSFiddle with the needed environment. Maybe someone can tell me what I'm doing wrong.

Oliver
  • 43,366
  • 8
  • 94
  • 151

1 Answers1

1

Your test fails because the selector functions in the expected and actual cases are not referentially equivalent.

The function selectDomainMessage returns a function returned by createSelector; and each time createSelector runs, it returns a new function.

For your test to pass, you can capture the return function of createSelector as a variable and have selectDomainMessage return that:

const selector = createSelector(selectDomain(), (domain) => domain.get('message'))
const selectDomainMessage = () => selector;

Modified JSFiddle

Jonathan Huang
  • 2,076
  • 17
  • 14