web-dev-qa-db-fra.com

Comment tester un composant natif de React qui importe un module natif personnalisé avec Jest?

Voici un composant simple que j'essaie de tester avec React Native 0.39 et Jest 18:

// index.ios.js

import React, { Component } from 'react';
import { AppRegistry, NativeModules, View } from 'react-native';

export default class TestProject extends Component {
  componentDidMount() {
    NativeModules.TestModule.test();
  }

  render() {
    return <View style={{ flex: 1 }} />;
  }
}

AppRegistry.registerComponent('TestProject', () => TestProject);

Voici TestModule et sa méthode test:

// ios/TestProject/TestModule.m

#import "TestModule.h"

@implementation TestModule

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(test){
  NSLog(@"This is a test");
}

@end

Le test suivant échoue avec l'erreur TypeError: Cannot read property 'test' of undefined:

// __tests__/index.ios.js

import 'react-native';
import renderer from 'react-test-renderer';
import React from 'react';
import Index from '../index.ios.js';

it('renders correctly', () => {
  const tree = renderer.create(
    <Index />
  );
});

J'ai lu la documentation Jest sur la manière de simuler des modules natifs à l'aide de jest.mock , mais je ne sais toujours pas comment étendre le modèle de Jest de NativeModules pour inclure ma classe TestModule ci-dessus.

10
andybangs

Vous pouvez simplement ajouter une maquette où votre module natif devrait être:

import {
  NativeModules,
} from 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';

describe('TestProject', () => {
  beforeEach(() => {
    NativeModules.TestModule = { test: jest.fn() } 
  });
  ...
});
12
rgoldfinger

Jest est un outil de test JavaScript, il n'exécute pas le code que vous avez écrit en Objective C/Swift/Java dans un module natif. Vous pouvez simuler les fonctionnalités d'un module natif de sorte que vous puissiez l'appeler à partir de JavaScript par l'approche que vous avez associée. par exemple.

jest.mock('NetInfo', () => {
  return {
    isConnected: {
      fetch: () => {
        return new Promise((accept, resolve) => {
          accept(true);
        })
      }
    }
  }
});
2
vonovak

Cela a également échoué pour moi (réactif natif 0.57.5, 23.6.0 blague). J'ai pu trouver une solution, mais c'était totalement différent (et dans mon cas, une solution plus élégante) qu'ici.

Découvrez le billet que j'ai classé pour plus de détails.

En gros, je devais avoir NativeModules étoffé par une fonction passée en tant que second paramètre à jest.mock () et le mettre dans un script exécuté au début de chaque test en utilisant l'option setupFiles config de Jest .

0
jebrii

De cette façon, vous vous moquerez une fois (avant que la blague ne commence)

jest.config.js

module.exports = {
  preset: 'react-native',
  setupFiles: ['./__mocks__/your-native-bridge.js']
};

__mocks__/your-native-bridge.js

import {NativeModules} from 'react-native';

NativeModules.YourNativeBridge = {
  property: jest.fn()
};

N'oubliez pas de vous moquer de toutes les fonctions possibles, propriétés dans YourNativeBridge

0
gr3g
#__mocks__/react-native-modules

const ReactNative = require('react-native')

ReactNative.NativeModules = {
  Defaults: {
    RU: {
      publicKey: '',
      privateKey: '',
    },
  },
}

module.exports = ReactNative

et alors

# in test file
jest.mock('react-native-modules')
import 'react-native-modules'
0
stereodenis