Expo TypeError 的笑话模拟权限:无法读取未定义的属性“askAsync”
Posted
技术标签:
【中文标题】Expo TypeError 的笑话模拟权限:无法读取未定义的属性“askAsync”【英文标题】:Jest Mocking Permissions of Expo TypeError: Cannot read property 'askAsync' of undefined 【发布时间】:2019-10-19 20:33:51 【问题描述】:我在嘲笑 expo 和 Permissions 模块,但是在调用 Permissions.AskAsync Permissions 时未定义。
问题看起来像这个问题。 Using Jest to mock named imports
使用了提供的答案,但没有用。
我已经嘲笑了 axios,它有效。对 expo 模块做同样的事情是行不通的。
我要测试的功能:
checkPermission = async () =>
const statusCamera = await Permissions.askAsync(Permissions.CAMERA);
// console.log(statusCamera);
this.setState(cameraPermission: statusCamera);
const statusCameraRoll = await Permissions.askAsync(Permissions.CAMERA_ROLL);
this.setState(cameraRollPermission: statusCameraRoll);
;
测试:
describe("Test the Permission function", () =>
it('should return rejected permission.', async function ()
const wrapper = shallow(<Photo2/>);
const instance = wrapper.instance();
await instance.checkPermission();
expect(instance.state("cameraPermission")).toBeFalsy();
);
);
我用于博览会的模拟:
jest.mock('expo', ()=>(
Permissions:
askAsync: jest.fn()
))
并尝试过 (在 mocks/expo.js 文件中)
export default
Permissions:
askAsync: jest.fn(() =>
return "SOMETHING"
)
并尝试过 (在 mocks/expo.js 文件中)
jest.mock('expo', ()=>(
Permissions:
askAsync: jest.fn()
));
错误:“TypeError:无法读取未定义的属性‘askAsync’”
此错误发生在调用Permissions.askAsyc
的行上。所以权限是未定义的。 (也检查了console.log(Permissions)
我预计 instance.state("cameraPermission")
是虚假的,但它在到达该行之前就崩溃了。
【问题讨论】:
【参考方案1】:由于 expo 将包更改为import * as Permissions from 'expo-permissions';
您只需要创建“mocks/expo-permissions.js”并拥有它:
export const getAsync = jest.fn(permissions => Promise.resolve());
export const askAsync = jest.fn(permissions => Promise.resolve());
【讨论】:
【参考方案2】:teerryn's answer 是正确的,是一个好的开始。添加更多细节:
-
除非您为 Jest 配置了不同的
roots
,否则您应该将模拟文件放在 __mocks__/expo-permissions.js
中,其中 __mocks__
是与您的 node_modules
文件夹处于同一级别的目录。请参阅 mocking node modules 上的 Jest 文档。
由于我们模拟模块的方式,传入的permissions
参数将是未定义的,因此您需要模拟要使用的权限类型。只需要像export const CAMERA_ROLL = 'camera_roll';
这样简单的东西
如果您想根据传入的权限类型做出不同的响应(例如,允许Permissions.CAMERA
但拒绝Permissions.CAMERA_ROLL
和所有其他类型),您可以模拟askAsync
函数的实现。例如,您的 __mocks__/expo-permissions.js
文件如下所示:
export const CAMERA = 'camera';
export const CAMERA_ROLL = 'camera_roll';
export const askAsync = jest.fn().mockImplementation((permissionType) =>
const responseData = permissionType === CAMERA ? status: 'granted' : status: 'undetermined' ; // you could also pass `denied` instead of `undetermined`
return Promise.resolve(responseData);
);
【讨论】:
【参考方案3】:问题是您处理异步测试不正确(您的 checkPermission()
函数是异步的)。有几种方法可以告诉你要测试异步函数。 Here are a few ways.
这里是您问题的快速解决方案:
...
import Permissions from 'expo';
...
jest.mock('expo', () => (
Permissions:
askAsync: jest.fn(),
));
...
describe("Test the Permission function", () =>
it('should return rejected permission.', () =>
Permissions.askAsync.mockImplementation( permission => return status: 'granted'; ); // if you want to add some sort of custom functionality
const wrapper = shallow(<Photo2/>);
const instance = wrapper.instance();
return instance.checkPermission().then(data =>
expect(instance.state("cameraPermission")).toBeFalsy();
);
);
);
【讨论】:
以上是关于Expo TypeError 的笑话模拟权限:无法读取未定义的属性“askAsync”的主要内容,如果未能解决你的问题,请参考以下文章
反应笑话单元测试用例TypeError:无法读取未定义的属性'then'
Expo 网络响应超时,无法在 Android 模拟器上运行 Expo 应用