I'm trying to test my redux-saga functions by using Redux Saga Test Plan library and I'm stuck due to delay functions in my saga.
If I remove the line, yield delay(1000)
all tests pass without any error.
saga.js
export function* addWorkoutSaga({ payload }) {
try {
yield put(beginAjaxCall());
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) {
console.log(error)
yield put(addWorkout.failure({ errorMessage: error.statusText }));
yield call(toast.error, "Error occured. Please try again.");
}
}
saga.test.js
import {
call,
put,
//takeLatest,
delay
} from 'redux-saga/effects';
import * as matchers from 'redux-saga-test-plan/matchers';
import { expectSaga } from 'redux-saga-test-plan';
import { throwError } from 'redux-saga-test-plan/providers';
import {
fetchWorkouts,
addWorkout,
//editWorkout,
deleteWorkout
} from '../../actions/workoutApiActionsForSaga';
import { WorkoutService } from "../../services";
import {
fetchWorkoutsSaga,
deleteWorkoutSaga,
addWorkoutSaga
} from '../workouts.saga'
describe('testing Workouts Sagas with redux-saga-test-plan', () => {
const fakeAddPayload = {
payload: {
id: '6e8dbbc8-233f-41b1-ade3-ca568b35918c',
date: '2019-05-27T18:10:35.282Z',
workoutType: 'Running',
calories: 100
}
};
const errorToThrow = {
statusText: 'custom Error Message'
};
it('should call addWorkoutSaga function', () => {
return expectSaga(addWorkoutSaga, fakeAddPayload)
.provide([
[matchers.call.fn(delay), null],
[matchers.call.fn(WorkoutService.add), null],
[matchers.call.fn(fetchWorkoutsSaga), null]
])
.call(WorkoutService.add, fakeAddPayload.payload)
.put(addWorkout.success())
.call(fetchWorkoutsSaga)
.run();
});
});
When I ran the test, I got the following error because expected value is not equal to the actual value.
Expected
--------
{ '@@redux-saga/IO': true,
combinator: false,
type: 'CALL',
payload:
{ context: null,
fn: [Function: add],
args:
[ { id: '6e8dbbc8-233f-41b1-ade3-ca568b35918c',
date: '2019-05-27T18:10:35.282Z',
workoutType: 'Running',
calories: 100 } ] } }
Actual:
------
1. { '@@redux-saga/IO': true,
combinator: false,
type: 'CALL',
payload: { context: null, fn: [Function: delayP], args: [ 1000 ] } }
at new SagaTestError (node_modules/redux-saga-test-plan/lib/shared/SagaTestError.js:17:57)
at node_modules/redux-saga-test-plan/lib/expectSaga/expectations.js:67:13
at node_modules/redux-saga-test-plan/lib/expectSaga/index.js:563:7
at Array.forEach (<anonymous>)
at checkExpectations (node_modules/redux-saga-test-plan/lib/expectSaga/index.js:562:18)
It seems to me that, the error is related to delay
function. When I tried to change the delay function to yield call(delay, 1000)
, it throws this error
Error: instead of writing `yield call(delay, 1000)` where delay is an effect from `redux-saga/effects` you should write `yield delay(1000)`
If I changed the line to yield call(delay(1000));
, it showed the following different error
Error: call: argument of type {context, fn} has undefined or null `fn`
Could you please help me how I could test my saga with delays? I don't want to remove the delay statements in the code to make the tests pass.