Jest中Mock的NativeModules方法onNextAction为何显示undefined?
问题分析与解决方案
我来帮你拆解两个核心问题,这就是为什么你遇到undefined和TypeError的原因:
1. 为什么onNextAction是undefined?
Jest的jest.mock()方法有一个特殊行为:它会被自动提升到当前模块代码的最顶部执行。
看你原来的代码顺序:
const mockOnNextAction = jest.fn(() => { then: jest.fn(); }); jest.mock('NativeModules', () => { return { MyNativeModule: { onNextAction: mockOnNextAction } }; });
当Jest处理这段代码时,会先执行jest.mock(),但此时mockOnNextAction还没有被定义(变量定义在jest.mock()之后),所以MyNativeModule.onNextAction就被赋值成了undefined——这就是你打印出undefined的根本原因。
2. 为什么会出现Cannot read property 'then' of undefined?
就算解决了第一个问题,你的mockOnNextAction写法也有问题:
const mockOnNextAction = jest.fn(() => { then: jest.fn(); });
这里的箭头函数用了花括号{}但没有显式return,所以它默认返回undefined。被测代码里调用onNextAction().then()时,相当于在undefined上访问then属性,自然会抛出TypeError。
修正后的完整代码示例
方案一:在jest.mock工厂函数内直接定义mock(推荐)
这种方式避免了变量提升的问题,同时让mock逻辑更内聚:
// 直接在mock工厂函数里创建所有需要的mock jest.mock('NativeModules', () => { // 先定义then方法的mock const mockThen = jest.fn(); // 定义onNextAction,返回包含then的对象 const mockOnNextAction = jest.fn(() => ({ then: mockThen })); return { MyNativeModule: { onNextAction: mockOnNextAction, // 别忘了mock被测代码里调用的executeSomeChecks方法 executeSomeChecks: jest.fn() } }; }); test('should trigger onNextAction and its then callback', () => { const { MyNativeModule } = require('NativeModules'); // 执行被测方法 MyNativeModule.executeSomeChecks(); // 验证onNextAction被调用 expect(MyNativeModule.onNextAction).toHaveBeenCalled(); // 验证then方法被调用(从mock的返回结果里获取then) expect(MyNativeModule.onNextAction.mock.results[0].value.then).toHaveBeenCalled(); });
方案二:返回真实Promise(更贴近实际异步场景)
如果你的onNextAction实际返回的是Promise,直接mock成Promise会更符合真实逻辑:
jest.mock('NativeModules', () => ({ MyNativeModule: { onNextAction: jest.fn(() => Promise.resolve()), executeSomeChecks: jest.fn() } })); // 用async/await编写异步测试 test('should handle onNextAction promise', async () => { const { MyNativeModule } = require('NativeModules'); MyNativeModule.executeSomeChecks(); expect(MyNativeModule.onNextAction).toHaveBeenCalled(); // 等待Promise完成,确保then回调执行 await MyNativeModule.onNextAction(); // 如果需要验证then里的业务逻辑,可以调整被测代码或mock的实现 });
内容的提问来源于stack exchange,提问作者bsky
相关产品推荐
相关产品推荐

