2
votes

Jest Mocking Permissions of Expo TypeError: Impossible de lire la propriété 'askAsync' de undefined

Je me moque de l'expo et du module Autorisations, mais lors de l'appel de Permissions.AskAsync Permissions n'est pas défini.

Le problème ressemble à cette question. Utilisation de Jest pour simuler des importations nommées

J'ai utilisé la réponse fournie, mais cela n'a pas fonctionné.

Je me suis moqué de l'axios, qui fonctionne. Faire la même chose pour le module expo ne fonctionne pas.

La fonction que je veux tester:

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

Le test:

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

    }
}

La maquette que j'utilise pour l'expo:

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

et j'ai essayé (Dans le fichier mocks/expo.js)

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();
    });
});

et essayé (Dans le fichier mocks/expo.js)

    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});
    };

Erreur: "TypeError: Impossible de lire la propriété 'askAsync' de undefined"

Cette erreur se produit sur la ligne où Permissions.askAsyc est appelé. Les autorisations ne sont donc pas définies. (Je l'ai également vérifié avec console.log(Permissions)

Je m'attendais à ce que instance.state ("cameraPermission") soit faux, mais il plante avant d'arriver à cette ligne.


0 commentaires

3 Réponses :


0
votes

Le problème est que vous ne gérez pas correctement les tests asynchrones (votre fonction checkPermission () est asynchrone). Il existe plusieurs façons de dire à Jest que vous souhaitez tester une fonction asynchrone. Voici quelques moyens.

Voici une solution rapide à votre problème:

...

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();
        });
    });
});


0 commentaires

1
votes

Depuis expo, changez les packages en import * en tant que permissions de 'expo-permissions';

Il vous suffit de créer "mocks / expo-permissions.js" et d'avoir:

export const getAsync = jest.fn(permissions => Promise.resolve());
export const askAsync = jest.fn(permissions => Promise.resolve());


0 commentaires

1
votes

La

réponse de teerryn est correcte et constitue un bon début. Pour ajouter quelques détails supplémentaires:

  1. Sauf si vous avez configuré des racines différentes pour Jest, vous devez placer votre fichier simulé dans __mocks __ / expo-permissions.js __mocks__ est un répertoire au même niveau que votre dossier node_modules . Consultez la documentation Jest sur les modules de nœuds moqueurs .
  2. L'argument permissions transmis ne sera pas défini en raison de la façon dont nous nous moquons du module, vous devrez donc vous moquer des types d'autorisations que vous souhaitez utiliser. Juste besoin de quelque chose de simple comme export const CAMERA_ROLL = 'camera_roll';
  3. Si vous souhaitez répondre différemment en fonction du type d'autorisation transmis (par exemple, autorisez Permissions.CAMERA mais refusez les Permissions.CAMERA_ROLL et tous les autres types), vous peut se moquer de l'implémentation de la fonction askAsync . Par exemple, votre fichier __mocks __ / expo-permissions.js ressemblerait à ceci:
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);
});


0 commentaires