【问题标题】:how to mock async PermissionsAndroid.request in jest?如何开玩笑地模拟 async PermissionsAndroid.request?
【发布时间】:2021-04-18 09:32:54
【问题描述】:

我在本机反应中有这段代码我想做一个测试:

const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
          {
            title: 'Device current location permission',
            message: 'Allow app to get your current location',
            buttonNeutral: 'Ask Me Later',
            buttonNegative: 'Cancel',
            buttonPositive: 'OK',
          }
        );

我在这里寻找答案,但似乎不起作用:How to mock PermissionAndroid from react native

jest.doMock('react-native/Libraries/PermissionsAndroid/PermissionsAndroid', () => ({
  ...jest.requireActual('react-native/Libraries/PermissionsAndroid/PermissionsAndroid'),
  request: () => ({
    [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]: PermissionsAndroid.RESULTS.GRANTED,
  }),
  check: () => true,
}));

在 ios 上我这样做很快:

jest.spyOn(Geolocation, 'requestAuthorization').mockResolvedValue('granted');

我似乎想不出如何在 android 中做到这一点?

【问题讨论】:

    标签: react-native jestjs


    【解决方案1】:

    我可以建议您尝试使用 react-native-permissions。它已经有一个您可以使用的mock file。您可以使用 Jest + React 测试库 Native。

    在我的例子中,我使用了 jest-setup.js 文件

    import {jest} from '@jest/globals';
    
    jest.mock('react-native-permissions', () =>
      require('react-native-permissions/mock'),
    );
    

    然后在你的 package.json 文件中配置 jest

    "jest": {
        "preset": "react-native",
        "setupFilesAfterEnv": [
          "@testing-library/jest-native/extend-expect"
        ],
        "transformIgnorePatterns": [
          "node_modules/(?!(jest-)?react-native-permissions|)"
        ],
        "setupFiles": [
          "./jest-setup.js"
        ]
      }
    

    对于地理定位服务,我在 __mocks__/react-native-geolocation-service.js 内创建了一个 react-native-geolocation-service

    export default {
      getCurrentPosition: jest.fn().mockImplementation(successCallback => {
        const position = {
          coords: {
            latitude: 57.7,
            longitude: 11.93,
          },
        };
        successCallback(position);
      }),
    };
    

    在你的 App 组件中你可以有这个

    import React, {useEffect, useState} from 'react';
    import { View } from 'react-native';
    import {check, request, PERMISSIONS, RESULTS} from 'react-native-permissions';
    import Geolocation from 'react-native-geolocation-service';
    
    const App = () => {
      const [location, setLocation] = useState(null);
    
      const handleLocationPermission = async () => {
        let permissionCheck = '';
        if (Platform.OS === 'ios') {
          permissionCheck = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
    
          if (permissionCheck === RESULTS.DENIED) {
            const permissionRequest = await request(
              PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
            );
            permissionRequest === RESULTS.GRANTED
              ? console.warn('Location permission granted.')
              : console.warn('Location perrmission denied.');
          }
        }
    
        if (Platform.OS === 'android') {
          permissionCheck = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
    
          if (permissionCheck === RESULTS.DENIED) {
            const permissionRequest = await request(
              PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
            );
            permissionRequest === RESULTS.GRANTED
              ? console.warn('Location permission granted.')
              : console.warn('Location perrmission denied.');
          }
        }
      };
    
      useEffect(() => {
        handleLocationPermission();
      }, []);
    
      useEffect(() => {
         Geolocation.getCurrentPosition(
            position => {
                const {latitude, longitude} = position.coords;
                setLocation({latitude, longitude});
         },
         error => {
           console.log(error.code, error.message);
         },
         {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
          );
         }, []);
      
      return (<View></View>)
    }
    

    然后在您的测试文件中,您可以使用 React Testing Library Native 测试行为。

    import React from 'react';
    import {render, waitFor} from '@testing-library/react-native';
    import App from '../App';
    import {check} from 'react-native-permissions';
    import Geolocation from 'react-native-geolocation-service';
    
    describe('<UserScreen />', () => {
      test('should check for permissions', async () => {
        render(<App />);
    
        await waitFor(() => {
          expect(check).toHaveBeenCalledTimes(1);
          expect(Geolocation.getCurrentPosition).toHaveBeenCalledTimes(1);
        });
      });
    });
    

    我在我的网站上写了一个类似且更详细的Post

    【讨论】:

      猜你喜欢
      • 2020-11-18
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 2020-08-20
      • 2021-05-27
      • 2022-01-24
      • 1970-01-01
      • 2018-07-25
      相关资源
      最近更新 更多