redux-saga-test-plan icon indicating copy to clipboard operation
redux-saga-test-plan copied to clipboard

Testing problem using expectSaga or testSaga

Open gothraven opened this issue 4 years ago • 4 comments

Introduction

I have been using redux-saga-test-plan for a while now, I wrote a bunch of tests using this library and it was a great help, I thank everyone who helped for that, but today we noticed some issue with our tests.

Here is an example:

saga.ts

export function* testMe() {
  const result = yield call(someApiFunction);
  if (result == 'good') {
     yield put(someAction);
  }
}

Testing this saga can only be done using expectSaga since we need to provide the result of the call function so we can test various situations.

saga.test.ts

describe('testMe Saga', () => {
  it('should do some work', () => {
    expectSaga(testMe)
      .provide([
         [call(someApiFunction), 'good'],
      ])
      .put(someAction)
      .run();
  });
});

The problems

  • if somehow we change the testMe saga and make it put another action at the end, the test will not break.
  • the previous test can never be enough for making sure that the function doesn't do any other effect.
  • we can't do the same test using testSaga because we can't provide a return value for call

Conclusion

Maybe i'm missing something, or I'm not using the library right, but i want to know how we can test and make sure that the saga doesn't do any other effect, in this kind of circumstances.

gothraven avatar May 12 '20 18:05 gothraven

I'm incredibly late on this, but in case anyone else sees this and needs the answer, you can test the effects with the following:

describe('testMe Saga', () => {
  it('should do some work', () => {
    expectSaga(testMe)
      .provide([
         [call(someApiFunction), 'good'],
      ])
      .run()
      .then((result) => {
        const { effects } = result;

        // Verify only one action was put
        expect(effects.put).toHaveLength(1);

        // Verify the action data is correct
        expect(effects.put[0]).toEqual(
          put(someAction(expectedPayload))
        );
    })
  });
});

Brackets probably don't match up, but its the 'then' block that matters

mathewpan avatar Dec 15 '20 13:12 mathewpan

Hi, i had the same problem. All I had to do is to insert a return statement

describe('testMe Saga', () => {
  it('should do some work', () => {
    // 👇 This return is missing
    return expectSaga(testMe)
       ....
  });
});

uwinkler avatar Apr 13 '22 06:04 uwinkler

@uwinkler Can you please explain how that helps ?

gothraven avatar Apr 13 '22 09:04 gothraven

Any movement on this?

anwarhamr avatar Apr 27 '24 00:04 anwarhamr