Testing redux saga with a while loop and delay with redux-saga-test-plan

577 Views Asked by At

I have a saga that delays increments a progress from 0 to 100 over 2 seconds. After 2 seconds, the saga will dispatch an action to submit an error. I am at a loss on how to test this using redux-saga-test-plan.

import { put, delay, takeLatest } from "redux-saga/effects";
import { incrementProgress } from "../actions/progress";
import { SUBMIT_ORDER_ERROR } from "../actions/orders";
import { receiveError } from "../actions/errors";

const TOTAL_DELAY = 2000;
const INTERVAL = 200;
let progress = 0;

export function* processErrorOrder() {
    while (progress <= 100) {
        yield delay(INTERVAL);
        progress += TOTAL_DELAY / INTERVAL;
        yield put(incrementProgress(progress));
    }
    if (progress >= 100) {
        yield put(receiveError("Order time has elapsed"));
    }
    if (progress > 100) {
        yield delay(1200);
        progress = 0;
        yield put(incrementProgress(progress));
    }
}
1

There are 1 best solutions below

0
Lin Du On

saga.ts:

import { delay, put } from "redux-saga/effects";

export const incrementProgress = (payload) => ({ type: 'increment', payload })
export const receiveError = (payload) => ({ type: 'receiveError', payload })

const TOTAL_DELAY = 2000;
const INTERVAL = 200;
let progress = 0;

export function* processErrorOrder() {
  while (progress <= 100) {
    yield delay(INTERVAL);
    progress += TOTAL_DELAY / INTERVAL;
    yield put(incrementProgress(progress));
  }
  if (progress >= 100) {
    yield put(receiveError("Order time has elapsed"));
  }
  if (progress > 100) {
    yield delay(1200);
    progress = 0;
    yield put(incrementProgress(progress));
  }
}

saga.test.ts:

import { testSaga } from "redux-saga-test-plan"
import { processErrorOrder } from "./saga"

describe('63083917', () => {
  test('should pass', () => {
    const testApi = testSaga(processErrorOrder);
    let progress = 0;
    while (progress <= 100) {
      progress += 10;
      testApi.next()
        .delay(200)
        .next()
        .put({ type: 'increment', payload: progress })
    }

    testApi.next().put({ type: 'receiveError', payload: 'Order time has elapsed' });
    testApi.next().delay(1200).next().put({ type: 'increment', payload: 0 }).next().isDone()
  })
});

Test result:

 PASS   redux-saga-examples  packages/redux-saga-examples/src/stackoverflow/63083917/saga.test.ts
  63083917
    ✓ should pass (4 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |    66.67 |     100 |     100 |                   
 saga.ts  |     100 |    66.67 |     100 |     100 | 16-19             
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.978 s, estimated 3 s

package versions:

"redux-saga-test-plan": "^4.0.1",
"redux-saga": "^1.1.3"