Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Redux-Saga when catch error with jest

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?

like image 790
Hsueh-Jen Avatar asked Mar 23 '18 07:03

Hsueh-Jen


People also ask

How do I test Redux with jest?

Setting Up Redux can be tested with any test runner, however in the examples below we will be using Jest, a popular testing framework. Note that it runs in a Node environment, so you won't have access to the real DOM. Jest can instead use jsdom to emulate portions of the browser in a test environment.

How do you test a saga?

You would test a saga almost the same way you would while testing a normal function but sagas have this play/pause kind of behavior that you should take into account while testing. The process of testing a saga is simplified greatly due to the effects exposed via redux-saga, like call () for example.

Do I need to test Redux code?

As such, the Redux code can be treated as an implementation detail of the app, without requiring explicit tests for the Redux code in many circumstances. The general advice for testing an app using Redux is as follows: Use integration tests for everything working together.

How do you test a react app with Redux?

I.e. for a React app using Redux, render a <Provider> with a real store instance wrapping the component/s being tested. Interactions with the page being tested should use real Redux logic, with API calls mocked out so app code doesn't have to change, and assert that the UI is updated appropriately.


1 Answers

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 }));
  });
});
like image 163
Hsueh-Jen Avatar answered Oct 31 '22 06:10

Hsueh-Jen