React Native中redux-saga单元测试的正确写法与示例咨询
Redux Saga 单元测试实现方案
前置准备
首先需要调整你的 saga 文件,将内部的 getUsers、getProfiles 函数也导出,方便单独测试:
// 原有代码不变,新增导出 export function* getUsers(action) { /* 原有逻辑 */ } export function* getProfiles(action) { /* 原有逻辑 */ } export function* usersSaga() { /* 原有逻辑 */ }
需要覆盖的测试逻辑点
- 根saga
usersSaga正确绑定了对应 action 类型和处理函数 - 接口请求成功场景:正确调用对应 API、分发加载成功的 action
- 接口请求失败场景:正确执行错误处理逻辑、分发加载失败的 action
基础实现示例
以下提供两种实现方式,第一种为无额外依赖的原生 Generator 迭代写法,第二种为常用的 redux-saga-test-plan 简化写法。
方式1:原生 Generator 迭代测试(无需额外依赖)
import { call, put, takeLatest } from 'redux-saga/effects'; import { usersSaga, getUsers } from '../sagas/users/'; import api from '你的api文件路径'; import userConstants from '你的常量文件路径'; import errorHandler from '你的错误处理文件路径'; describe('Users Saga', () => { // 测试根saga监听逻辑 it('根saga正确监听对应action', () => { const gen = usersSaga(); // 断言第一个yield是监听GET_USERS expect(gen.next().value).toEqual(takeLatest(userConstants.GET_USERS, getUsers)); // 断言第二个yield是监听GET_USER_PROFILES expect(gen.next().value).toEqual(takeLatest(userConstants.GET_USER_PROFILES, getProfiles)); // 断言执行结束 expect(gen.next().done).toBe(true); }); // 测试getUsers正常请求流程 it('getUsers正常请求时正确调用api并分发成功action', () => { const mockAction = { payload: { id: 123 } }; const mockResData = [{ id: 1, name: '测试用户' }]; const gen = getUsers(mockAction); // 第一步:调用getUsers接口 expect(gen.next().value).toEqual(call(api.users.getUsers, { id: 123 })); // 第二步:传入接口返回值,断言分发成功action expect(gen.next({ data: mockResData }).value).toEqual(put({ type: userConstants.LOAD_USERS, payload: mockResData })); // 断言执行结束 expect(gen.next().done).toBe(true); }); // 测试getUsers异常请求流程 it('getUsers请求失败时正确执行错误处理并分发失败action', () => { const mockAction = { payload: { id: 123 } }; const mockError = new Error('接口请求失败'); const gen = getUsers(mockAction); // 第一步:调用接口 gen.next(); // 抛出错误,断言调用错误处理函数 expect(gen.throw(mockError).value).toEqual(call(errorHandler, mockError)); // 断言分发失败action expect(gen.next().value).toEqual(put({ type: userConstants.LOAD_USERS_FAIL })); // 断言执行结束 expect(gen.next().done).toBe(true); }); })
方式2:使用redux-saga-test-plan简化测试
首先安装依赖:
npm install redux-saga-test-plan --save-dev
测试代码示例:
import { expectSaga } from 'redux-saga-test-plan'; import { call } from 'redux-saga/effects'; import { getUsers } from '../sagas/users/'; import api from '你的api文件路径'; import userConstants from '你的常量文件路径'; import errorHandler from '你的错误处理文件路径'; describe('Users Saga', () => { it('getUsers正常请求流程测试', () => { const mockAction = { payload: { id: 123 } }; const mockResData = [{ id: 1, name: '测试用户' }]; return expectSaga(getUsers, mockAction) // mock接口返回值 .provide([ [call(api.users.getUsers, { id: 123 }), { data: mockResData }] ]) // 断言分发了成功的action .put({ type: userConstants.LOAD_USERS, payload: mockResData }) .run(); }); it('getUsers异常请求流程测试', () => { const mockAction = { payload: { id: 123 } }; const mockError = new Error('接口请求失败'); return expectSaga(getUsers, mockAction) // mock接口抛出错误 .provide([ [call(api.users.getUsers, { id: 123 }), Promise.reject(mockError)] ]) // 断言调用了错误处理函数 .call(errorHandler, mockError) // 断言分发了失败的action .put({ type: userConstants.LOAD_USERS_FAIL }) .run(); }); })
getProfiles的测试逻辑和getUsers完全一致,替换对应的接口、常量即可。
内容的提问来源于stack exchange,提问作者Loki
相关产品推荐
相关产品推荐

