React Native单元测试:如何Mock expo-camera的requestCameraPermissionsAsync响应?
问题:Mock expo-camera权限方法不生效的原因及解决办法
我在为React Native组件编写单元测试时,需要Mock expo-camera的requestCameraPermissionsAsync()方法,让它始终返回status: 'granted'。
尝试了以下代码但未生效:
jest.mock('expo-camera', () => { const PermissionsCamera = jest.requireActual('expo-camera'); return { ...PermissionsCamera, requestCameraPermissionsAsync: () => new Promise(resolve => resolve({granted: true, status: 'granted'})), }; });
组件中的实际调用代码:
import {Camera} from 'expo-camera' useEffect(() => { (async () => { const {status} = await Camera.requestCameraPermissionsAsync(); // 当status为'granted'时的额外逻辑 })(); }, []);
问题原因
你的Mock代码未生效的核心问题是导出结构不匹配:expo-camera的requestCameraPermissionsAsync方法是挂载在Camera对象下的,而非顶层导出。你之前的Mock把方法放在了导出对象的顶层,和组件中调用的Camera.requestCameraPermissionsAsync完全不是同一个引用,自然不会生效。
解决办法
调整Mock的结构,将requestCameraPermissionsAsync放在Camera对象内部,同时用jest.fn()包裹方法(方便后续验证调用情况):
jest.mock('expo-camera', () => { const actualModule = jest.requireActual('expo-camera'); return { ...actualModule, Camera: { ...actualModule.Camera, requestCameraPermissionsAsync: jest.fn(() => Promise.resolve({ granted: true, status: 'granted' }) ), }, }; });
额外优化点
- 用
Promise.resolve()替代手动创建新Promise,写法更简洁 - 通过
jest.fn()创建Mock函数后,可在测试中通过Camera.requestCameraPermissionsAsync.mock.calls验证方法的调用次数和参数
内容的提问来源于stack exchange,提问作者fmsthird
相关产品推荐
相关产品推荐

