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:
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?
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.
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.
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.
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.
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 }));
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With