Blog>
Snippets

Using the 'cloneableGenerator' from 'redux-saga/utils' for Cloning

Demonstrates the use of 'cloneableGenerator' to clone a generator function, allowing for testing different branches of a generator's flow without side effects.
import { call, put } from 'redux-saga/effects';
import { fetchPostsApi } from './api';
import { postsReceived, postsFailed } from './actions';
import { cloneableGenerator } from 'redux-saga/utils';
Import necessary saga effects, the API function for fetching posts, action creators, and the cloneableGenerator function from redux-saga/utils.
function* fetchPostsSaga() {
  try {
    const posts = yield call(fetchPostsApi);
    yield put(postsReceived(posts));
  } catch (error) {
    yield put(postsFailed(error));
  }
}
Define a generator function that attempts to fetch posts using fetchPostsApi and dispatches either a success action with the posts or a failure action with the error.
const fetchPostsGenerator = cloneableGenerator(fetchPostsSaga)();
Creates a cloneable generator instance from our fetchPostsSaga which allows us to easily clone the generator state.
const successfulClone = fetchPostsGenerator.clone();
const failedClone = fetchPostsGenerator.clone();
Creates two clones of the generator: one for simulating a successful API call and another for simulating a failure.
// Testing successful API call
const posts = [{ id: 1, title: 'Post 1' }];
expect(successfulClone.next().value).toEqual(call(fetchPostsApi));
expect(successfulClone.next(posts).value).toEqual(put(postsReceived(posts)));
expect(successfulClone.next().done).toBe(true);
Test the successful path by simulating a successful API call that returns posts. Verify that the generator yields the expected effects in sequence and completes.
// Testing failed API call
const error = new Error('Failed to fetch posts');
expect(failedClone.next().value).toEqual(call(fetchPostsApi));
expect(failedClone.throw(error).value).toEqual(put(postsFailed(error)));
expect(failedClone.next().done).toBe(true);
Test the failure path by simulating a failed API call that throws an error. Verify that the generator yields the expected effects in sequence and completes.