Expo TypeError的Jest Mocking权限:无法读取未定义的属性“ askAsync”

时间:2019-06-04 10:07:37

标签: permissions mocking jestjs expo

我正在模拟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()
  }
}))

并尝试 (在文件模拟 /expo.js中)

export default {
    Permissions: {
        askAsync: jest.fn(() => {
            return "SOMETHING"
        })

    }
}

并尝试 (在文件模拟 /expo.js中)

jest.mock('expo', ()=>({
    Permissions: {
        askAsync: jest.fn()
    }
}));
  

错误:“ TypeError:无法读取未定义的属性'askAsync'”

此错误发生在调用Permissions.askAsyc的行中。因此权限是不确定的。 (还用console.log(Permissions)

我期望instance.state("cameraPermission")是虚假的,但是在到达该行之前会崩溃。

3 个答案:

答案 0 :(得分:1)

teerryn's answer是正确的,也是一个好的开始。要添加更多详细信息:

  1. 除非为Jest配置了不同的roots,否则应将模拟文件放在__mocks__/expo-permissions.js中,其中__mocks__是与node_modules文件夹相同级别的目录。请参阅mocking node modules上的Jest文档。
  2. 由于我们模拟模块的方式,传入的permissions参数将是不确定的,因此您需要模拟要使用的权限类型。只需要像export const CAMERA_ROLL = 'camera_roll';
  3. 这样的简单东西
  4. 如果您要基于传入的权限类型做出不同的响应(例如,允许Permissions.CAMERA但拒绝Permissions.CAMERA_ROLL和所有其他类型),则可以模拟{{1}的实现}函数。例如,您的askAsync文件如下所示:
__mocks__/expo-permissions.js

答案 1 :(得分:0)

问题是您对异步测试的处理不正确(您的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();
        });
    });
});

答案 2 :(得分:0)

自博览会起,将软件包更改为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());