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.

Test delay from redux-saga

See original GitHub issue

Background

I have a “gradual-backoff” built into a saga using Redux-saga’s delay() effect.

I am using expectSaga to write the test.

But in order to get the test to work I had to disable the delay.

Question

What is the best way to test the delay amount?

Code

“Back off” function that returns 1s, 2s, or 3s

const BACK_OFF_SERIES = [1000, 2000, 3000];
const backOff = attempt =>
  BACK_OFF_SERIES[Math.min(attempt, BACK_OFF_SERIES.length - 1)];

tryDownload saga

const MAX_ATTEMPTS = 3;
function* tryDownloadFiles(assets, downloadOptions) {
  for (let attempts = MAX_ATTEMPTS; attempts; attempts -= 1) {
    try {
      const urls = yield call(downloader, assets, downloadOptions);
      return urls;
    } catch (error) {
      if (attempts > 1) {
        yield call(delay, backOff(attempts));
      } else {
        yield put(
          showError({
            error: `${error}. Failed!`,
          })
        );
      }
    }
  }
}

And an expectSaga test that uses a provider bypass the delay:

const res = expectSaga(tryDownloadFiles, mockAssets, mockDownloadOptions)
  .provide([
    [matchers.call.fn(delay), null],
    [matchers.call.fn(downloader), throwError(mockError)],
  ])
  // .call(delay, backOff(3))
  // .call(delay, backOff(2))
  // .call(delay, backOff(1))
  .put(showError({ error: `${mockError}. Failed!` }))
  .run();

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:10

github_iconTop GitHub Comments

17reactions
ttcgcommented, Jun 18, 2019

This is how I did it. I have to check whether the name of the Function is ‘delayP’ or not. Otherwise, it mocks every calls in my *Saga() method.

Fake const provideDelay = ({ fn }, next) => (fn.name === 'delayP') ? null : next();

Usage to Test addWorkoutSaga

it('should call addWorkoutSaga function', () => {
        return expectSaga(addWorkoutSaga, fakeWorkoutPayload)
            .provide([
                { call: provideDelay },
                [matchers.call.fn(WorkoutService.add), null],
                [matchers.call.fn(fetchWorkoutsSaga), null]
            ])
            .call(WorkoutService.add, fakeWorkoutPayload.payload)
            .put(addWorkout.success())
            .call(fetchWorkoutsSaga)
            .run();
    });

addWorkoutSaga

export function* addWorkoutSaga({ payload }) {
    try {
        yield put(beginAjaxCall());

        // throw error intentionally for calories lower than 50
        if (payload.calories < 50)
            payload.calories = '';

        yield delay(1000);
        yield call(WorkoutService.add, payload);

        yield call(toast.success, "Item added successfully.");
        yield put(closeModal(Modal.AddWorkout));
        yield put(addWorkout.success());
        yield call(fetchWorkoutsSaga);
    }
    catch (error) {
        yield put(addWorkout.failure({ errorMessage: error.statusText }));
        yield call(toast.error, "Error occured.  Please try again.");
    }
}
9reactions
cobarxcommented, Apr 1, 2019

I’m trying to do something similar and am not sure how to simulate a delay in 4.0.0-beta2. In redux-saga 1.0.x, you can no longer use the yield call(delay, ms) approach and must call yield delay(ms) directly.

Any suggestions?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to test redux-saga delay - Stack Overflow
A good way to test Redux Saga calls is by using the call effect. In this case, you can slightly refactor your saga...
Read more >
Dispatching · GitBook - Redux Saga Test Plan
You can also dispatch actions while a saga is running. This is useful for delaying actions so Redux Saga Test Plan doesn't dispatch...
Read more >
Recipes | Redux-Saga
In the above example the apiRequest will be retried for 5 times, with a delay of 2 seconds in between. After the 5th...
Read more >
[Solved]-How to test redux-saga delay-Reactjs - appsloveworld
[Solved]-How to test redux-saga delay-Reactjs ... so if you import delay in two different modules it will be two different functions that have...
Read more >
Running asynchronous redux-saga tests - Level Up Coding
There are several ways to write asynchronous logic for your React app. The two that I have experience with are redux-thunk and redux-saga....
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