使用Jest测试Redux Saga的fetchStripeLocations方法遇问题求助
Redux Saga fetchStripeLocations方法Jest测试问题排查
我在使用Jest测试Redux Saga中的fetchStripeLocations方法时遇到问题,附上该Saga方法代码、测试用例及控制台截图,希望帮忙排查问题。已多次谷歌搜索但未找到解决方案,盼协助。
Saga方法代码
export function* fetchStripeLocations() { console.log('saga fetchStripeLocations called:'); try { const BE = yield select((state) => state.BE); const PaymentRequestFormReducer = yield select(state => state.PaymentRequestFormReducer.toJS()); const { stripeLocationsMap } = PaymentRequestFormReducer; const paymentsEnabled = isPaymentsEnabled(BE); if (!stripeLocationsMap.data && !stripeLocationsMap.isLoading && paymentsEnabled) { yield put(actionCreator.fetchingStripeLocations()); const url = actionCreator.URL.FETCH_STRIPE_LOCATIONS; const response = yield call(beAPIResource.get, url, {}, { topLoader: false, isPrimaryAPI: false, cancellable: false }); const { qcrEnabled, stripeLocationsMap } = response.data; yield put(actionCreator.setStripeLocations({ qcrEnabled, stripeLocationsMap })); } } catch (e) { yield put(actionCreator.setStripeLocations({ stripeLocationsMap: {} })); yield put(dataFetchingError(e, "Something went wrong please try again later")); } }
测试用例代码
import { testData } from "./TestReducerData"; import { commonTestData } from "../../../../../../__test__/commonTestData"; test('fetchStripeLocations testing should pass', async () => { const dispatchedActions = []; const stripeDummyData = iMap({ isLoading: false, data: null, qcrEnabled: false }); const mockData = { qcrEnabled : false, stripeLocationsMap: { isLoading: false, data: null, qcrEnabled: false } }; const mRequest = jest.fn(() => Promise.resolve(mockData)); const mockState = { BE: commonTestData, PaymentRequestFormReducer: testData.initialState }; await runSaga({ dispatch: (action) => dispatchedActions.push(action), getState: () => mockState, }, PaymentRequestFormSaga.fetchStripeLocations).done; console.log('dispatchedActions', dispatchedActions); console.log('mRequest.mock:', mRequest.mock); expect(mRequest.mock.calls.length).toBe(1); expect(dispatchedActions).toEqual([ActionCreator.setStripeLocations(mockData)]); });
控制台截图


问题排查及解决方案
API调用未被模拟
测试代码中定义了mRequest但并未替换Saga中实际使用的beAPIResource.get,导致真实API被调用而非模拟方法,因此mRequest.mock.calls.length始终为0。
解决:在测试前模拟API方法:jest.mock('path/to/beAPIResource', () => ({ get: jest.fn(() => Promise.resolve({ data: mockData })) }));状态判断条件未满足
Saga中需同时满足!stripeLocationsMap.data && !stripeLocationsMap.isLoading && paymentsEnabled才会执行后续逻辑,需确认:testData.initialState.toJS()返回的stripeLocationsMap是否符合data: null且isLoading: falseisPaymentsEnabled(commonTestData)是否返回true
解决:手动设置mock状态确保条件成立:
const mockState = { BE: commonTestData, PaymentRequestFormReducer: iMap({ stripeLocationsMap: { data: null, isLoading: false } }) };dispatch断言错误
Saga中会先dispatchactionCreator.fetchingStripeLocations(),再dispatchsetStripeLocations,测试预期只包含一个action不符合实际逻辑。
解决:修改断言为:expect(dispatchedActions).toEqual([ actionCreator.fetchingStripeLocations(), actionCreator.setStripeLocations(mockData) ]);
内容的提问来源于stack exchange,提问作者Rahul Mangal
相关产品推荐
相关产品推荐

