使用jest测试含selector的redux saga时报TypeError: env.getState错误
错误根因
TypeError: env.getState is not a function报错的核心原因是saga测试运行环境没有正确注入getState方法:yield select() 内部会调用saga运行环境内置的getState方法读取store状态,没有传入该方法时就会触发报错。没有用到select的saga不会调用该方法,所以测试可以正常运行。
修复方案
根据你常用的测试方式选择对应修复逻辑:
使用runSaga执行完整saga流测试
给runSaga的配置参数补全getState字段,自定义返回测试用的mock状态即可,示例代码:
import { runSaga } from 'redux-saga'; import targetSaga from './saga'; test('测试包含select调用的saga', async () => { // 构造符合你的业务store结构的mock状态 const mockStoreState = { user: { id: 123, isLogin: true }, // 其他state字段 }; const dispatched = []; await runSaga( { // 补全getState方法,直接返回构造的mock状态 getState: () => mockStoreState, dispatch: (action) => dispatched.push(action) }, targetSaga, // 此处传入saga所需的入参,没有则留空 ).toPromise(); // 后续执行你的断言逻辑 })
逐步迭代generator函数测试
如果是用逐步调用generator.next()的方式测试saga,不需要配置getState,直接在触发select后的next调用中传入selector的mock返回值即可:
import targetSaga from './saga'; import { select } from 'redux-saga/effects'; import userSelector from './selectors'; test('逐步测试saga逻辑', () => { const gen = targetSaga(); // 校验第一步是调用对应selector expect(gen.next().value).toEqual(select(userSelector)); // 传入selector的mock返回值,供后续saga逻辑使用 const mockSelectorRes = { id: 123, isLogin: true }; const nextEffect = gen.next(mockSelectorRes); // 后续断言其他effect逻辑 })
额外排查点
- 确认你的
redux-saga依赖版本和测试工具API匹配,v1.x及以上版本的runSaga参数结构和0.x版本存在差异,不要混用不同版本的API规则。 - 检查测试代码中是否手动修改了saga运行的env配置,意外删除了默认的
getState字段。
内容的提问来源于stack exchange,提问作者rmrider
相关产品推荐
相关产品推荐

