【问题标题】:Jest Mocking Permissions of Expo TypeError: Cannot read property 'askAsync' of undefinedExpo TypeError 的笑话模拟权限:无法读取未定义的属性“askAsync”
【发布时间】: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") 是虚假的,但它在到达该行之前就崩溃了。

【问题讨论】:

    标签: permissions mocking jestjs expo


    【解决方案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 是正确的,是一个好的开始。添加更多细节:

      1. 除非您为 Jest 配置了不同的 roots,否则您应该将模拟文件放在 __mocks__/expo-permissions.js 中,其中 __mocks__ 是与您的 node_modules 文件夹处于同一级别的目录。请参阅 mocking node modules 上的 Jest 文档。
      2. 由于我们模拟模块的方式,传入的permissions 参数将是未定义的,因此您需要模拟要使用的权限类型。只需要像export const CAMERA_ROLL = 'camera_roll'; 这样简单的东西
      3. 如果您想根据传入的权限类型做出不同的响应(例如,允许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();
                });
            });
        });
        

        【讨论】:

          猜你喜欢
          • 2018-10-29
          • 2021-10-29
          • 2021-10-26
          • 2022-06-28
          • 2019-06-10
          • 2017-06-27
          • 2022-06-30
          • 2020-11-19
          • 2018-06-17
          相关资源
          最近更新 更多