5

everyone. I test saga with jest framework. I can test my saga in normal situation. But I want to test the code in catch(), so I have to mock a error to trigger catch. I find some solution in redux-saga offical document and other stackoverflow answer. But I still have a problem.

when I use throw() in saga.test.js like the sample below, it will show "Error [object Object] thrown". So it can't really pass this test. I didn't see anyone ask same question. Could anyone help me? Thanks a lot.

Error result screen:

img1

api.js

const api = {
  fetchProductAPI() {
    return 'iphone';
  },
};
export default api;

saga.js

import { call, put } from 'redux-saga/effects';
import api from './api';

export default function* fetchProduct() {
  try {
    yield call(api.fetchProductAPI);
    yield put({ type: 'PRODUCTS_RECEIVED', product: 'iphone' });
  } catch (error) {
    yield put({ type: 'PRODUCTS_REQUEST_FAILED', error });
  }
}

saga.test.js

import { put, call } from 'redux-saga/effects';
import fetchProduct from './saga';
import api from './api';

describe('fetchProduct()', () => {
  it('try', () => {
    const gen = fetchProduct();
    expect(gen.next().value).toEqual(call(api.fetchProductAPI));
    expect(gen.next().value).toEqual(put({ type: 'PRODUCTS_RECEIVED', product: 'iphone' }));
  });
  it('catch', () => {
    const error = 'product not found';
    const gen = fetchProduct();
    expect(
      gen.throw({
        error: 'product not found',
      }).value
    ).toEqual(put({ type: 'PRODUCTS_REQUEST_FAILED', error }));
  });
});

The related solutions answer I found below:

Redux-Saga Error Handling

How to test API request failures with Redux Saga?

skyboyer
  • 15,149
  • 4
  • 41
  • 56
Hsueh-Jen
  • 217
  • 2
  • 9

2 Answers2

10

My friend help me to solve this problem. So I answer my question by myself...

I need to add gen.next() before I throw. Here is the solution code below.

it('catch', () => {
  const error = 'product not found';
  const gen = fetchProduct();
  gen.next(); //add gen.next() before throw
  expect(
    gen.throw('product not found').value).
    toEqual(put({ type: 'PRODUCTS_REQUEST_FAILED', error }));
  });
});
Hsueh-Jen
  • 217
  • 2
  • 9
0

You can do it easily with jest-generator. https://github.com/doniyor2109/jest-generator

it('catch', () => {
  const error = new Error('product not found');

  expect(fetchProduct()).toMatchYields([
    [call(api.fetchProductAPI), error],
    [put({ type: 'PRODUCTS_REQUEST_FAILED', error.message }))]
  ]);
});
doniyor2109
  • 474
  • 3
  • 16