如何从反应原生模拟 PermissionAndroid

Posted

技术标签:

【中文标题】如何从反应原生模拟 PermissionAndroid【英文标题】:How to mock PermissionAndroid from react native 【发布时间】:2020-09-14 11:16:13 【问题描述】:

我正在使用 React-native 构建一个 android 应用,并使用来自 react-native 的 PermissionsAndroid 来获取用户权限。

import PermissionsAndroid from 'react-native'

现在我正在编写单元测试,我需要根据权限验证组件行为。 因此我需要模拟 PermissionsAndroid。

有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

你可以直接从 react-native 模拟这个,就像:

    jest.doMock('react-native', () => (
      PermissionsAndroid: 
        request: (permission: string) => 
          //whatever you want
        ,
      ,
    ))

请注意,您可能会看到用于该单元测试的组件存在一些问题,即,如果您使用来自 React Native 的 <View> 而不是模拟它,它可能会显示错误。在这种情况下,您必须导入 <View>,然后将其包含在您的模拟中。

import  View  from 'react-native'
...

    jest.doMock('react-native', () => (
      View,
      PermissionsAndroid: 
        request: (permission: string) => 
          //whatever you want
        ,
      ,
    ))

【讨论】:

【参考方案2】:

只是嘲笑 jest.doMock('react-native', () => ( PermissionsAndroid: ... 对我不起作用。以下是我如何让它专门模拟 requestMultiplecheck

let fineLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let courseLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;

let fineLocationPermissionGranted = true;
let coarseLocationPermissionGranted = true;

const permissionsAndroidModule = jest.requireActual('react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js');
jest.doMock('react-native/Libraries/PermissionsAndroid/PermissionsAndroid', () => (
  ...permissionsAndroidModule,
  requestMultiple: () => 
    return 
      [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]: fineLocationPermissionResult,
      [PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION]: courseLocationPermissionResult,
    ;
  ,
  check: () => 
    return fineLocationPermissionGranted && coarseLocationPermissionGranted;
  ,
));

我已经包含了一些我在测试中使用的变量来操纵模拟结果,但基本上你需要模拟整个模块路径 ('react-native/Libraries/PermissionsAndroid/PermissionsAndroid'),然后包含你没有的模块的其余部分通过jest.requireActual嘲讽。

【讨论】:

【参考方案3】:

解决方法如下:

jest.mock(
  'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
  () => (
    PermissionsAndroid: 
      request: () => 
        true;
      ,
      check: () => 
        true;
      ,
    ,
  )
);

【讨论】:

【参考方案4】:
jest.mock('react-native//Libraries/PermissionsAndroid/PermissionsAndroid', () => 
  const PermissionsAndroid = jest.requireActual(
    'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
  );
  console.log(PermissionsAndroid);
  return 
    ...PermissionsAndroid,
    check: jest.fn(() => new Promise(resolve => resolve(true))),
    request: jest.fn(() => new Promise(resolve => resolve(true))),
  ;
);

【讨论】:

request: jest.fn(() => new Promise(resolve => resolve('granted'))) 在这一行中,我通过了 'granted' 而不是 true,它对我有用。谢谢!

以上是关于如何从反应原生模拟 PermissionAndroid的主要内容,如果未能解决你的问题,请参考以下文章

如何从反应原生应用程序制作 .ipa 文件

如何模拟反应原生I18nManager

你们如何测试复杂的反应原生应用程序?

如何在本机反应中模拟上下文消费者反应元素

如何从反应原生页面快速打开现有的 ViewController?

如何从反应原生桥将参数传递给swift类