question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unit testing with takeLatest or takeEvery

See original GitHub issue

From the examples I’ve seen, if you use a watcher saga that uses takeLatest or takeEvery, the tests do not ensure the saga is run after seeing the correct action dispatched.

For example here are my sagas.

function* getDataSaga(action) {
  try {
    const response = yield call(api.getData, action.payload);
    yield put(getDataSucceeded(response));
  } catch (e) {
    yield put(getDataFailed(e));
  }
}

function* watchGetDataSaga() {
  yield* takeLatest(GET_DATA, getDataSaga);
}

I could write some tests like this:

describe('My Saga', () => {
  it('should first call the getData api', () => {
    // arrange
    const action = {
      type: GET_DATA,
      payload: { foo: 'bar' },
    };
    const iterator = getDataSaga(action);
    const expectedYield = call(api.getData, action.payload);

    // act
    const actualYield = iterator.next().value;

    // assert
    expect(actualYield).to.deep.equal(expectedYield);
  });
});

However, I can’t write tests that make sure the saga is kicked off from a GET_DATA action. It seems to me the only way to do this sort of test is to use a while(true) in my getDataSaga instead of having the watchGetDataSaga. Is this the case, or is there a way around this?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:5
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

48reactions
npbeecommented, Jun 27, 2016

Not dumb! I’m no expert myself, but I’ll explain as I understand it.

Both of these basically have the same functional outcome. You can test both in the way we discussed above but the return values are different, so the tests would change.

The yield* expression is just a plain JS feature, and it essentially just allows to you to yield to nested iterables. In this context, doing yield* takeEvery would mean that you’re yielding to the every value that the takeEvery iterable itself yields. So to test yield* takeEvery, you’d be testing for what values takeEvery itself yields back to you, which means you need to know the internals of takeEvery.

When using yield call(takeEvery, ..), that’s a declarative effect from redux-saga and it will only ever yield one value and that is a CALL effect. You can easily test that the correct effect was yielded.

So long story short: functionally they are basically the same but testing call effects are easier.

I made another fiddle that might be more clear: https://jsfiddle.net/npbee/Lqreq12b/2/.

Hope that helps!

3reactions
Andaristcommented, Oct 10, 2017

call(takeEvery, ...) is old recommendation, please just use takeEvery(...) from the redux-saga/effects ‘subpackage’

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to test all effect with redux-saga-test-plan. ...
saga'; import { takeEvery, takeLatest } from '@redux-saga/core/effects'; describe('Unit tests', () => { test('Test all effect', ...
Read more >
Saga Helpers · GitBook
Redux Saga Test Plan also offers assertions for the saga helper effects takeEvery , takeLatest , and throttle . These helpers come in...
Read more >
Testing side effects using redux saga
In this post I'll try to show you how convenient it is to test side effects ... const { takeEvery, takeLatest } =...
Read more >
Testing Sagas
There are two main ways to test Sagas: testing the saga generator function step-by-step or running the full saga and.
Read more >
Unit Testing Redux Sagas with Jest | by Gaurav KC
Our sagas being generator functions always yield effects which are saga factory functions like takeEvery, put, call etc. We can test each yield ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found