jfairbank / redux-saga-test-plan

Test Redux Saga with an easy plan.
http://redux-saga-test-plan.jeremyfairbank.com
MIT License
1.25k stars 127 forks source link

Can expectSaga be run in such a way that ANY unexpected yield would result in a failed test? #389

Open etodanik opened 2 years ago

etodanik commented 2 years ago

From what I see currently, expectSaga() only fails a test if an effect was expected, but that effect was run with the wrong arguments.

Given the same saga:

function* mySaga() {
  yield put({ type: "Count", payload: { ms: 1 } });
  yield call(getNumber, 100);
  yield put({ type: "Count", payload: { ms: 2 } });
  yield call(getNumber, 100);
  yield put({ type: "Count", payload: { ms: 3 } });
  yield call(getNumber, 100);
}

✅ For example, this will pass:

await expectSaga(mySaga)
      .put({ type: "Count", payload: { ms: 1 } })
      .call(getNumber, 100)
      .put({ type: "Count", payload: { ms: 2 } })
      .call(getNumber, 100)
      .put({ type: "Count", payload: { ms: 3 } })
      .call(getNumber, 100)
      .silentRun(50);

✅ This will also pass (we totally don't test for any calls):

await expectSaga(mySaga)
      .put({ type: "Count", payload: { ms: 1 } })
      .put({ type: "Count", payload: { ms: 2 } })
      .put({ type: "Count", payload: { ms: 3 } })
      .silentRun(50);

✅ Even this will pass (even though we are missing a test for call in between there):

await expectSaga(mySaga)
      .put({ type: "Count", payload: { ms: 1 } })
      .call(getNumber, 100)
      .put({ type: "Count", payload: { ms: 2 } })
      .put({ type: "Count", payload: { ms: 3 } })
      .call(getNumber, 100)
      .silentRun(50);

🚨 Only this will fail:

await expectSaga(mySaga)
      .put({ type: "Count", payload: { ms: 1 } })
      .call(getNumber, 100)
      .put({ type: "Count", payload: { ms: 2 } })
      .call(getNumber, 50) // we provided wrong arguments
      .put({ type: "Count", payload: { ms: 3 } })
      .call(getNumber, 100)
      .silentRun(50);

This is highly problematic behaviour for me because it leaves a lot of room for random and unexpected effects to be yielded without the test alerting me to it.

Is there a way to make expectSaga() strict? I would love it if it fails the test if we skipped an effect, or called effects in the wrong order.

etodanik commented 2 years ago

P.S I am aware that testSaga is made for unit tests, but I have to test channels, which aren't really supported by testSaga. It'd still be nice to be able to test order of things.

tatemz commented 2 years ago

+1 to this feature. I find myself prefixing a lot of conditional behavior with .not