如何测试使用Jest导入自定义本机模块的React Native组件?

时间:2016-12-27 06:18:04

标签: ios facebook unit-testing react-native jestjs

这是一个我尝试使用React Native 0.39和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);

这是TestModule及其test方法:

// ios/TestProject/TestModule.m

#import "TestModule.h"

@implementation TestModule

RCT_EXPORT_MODULE();

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

@end

以下测试失败,错误为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 />
  );
});

我已经阅读了关于如何Mock native modules using jest.mock的Jest文档,但是仍然不清楚如何扩展Jest的NativeModules模拟以包含我的TestModule类。

5 个答案:

答案 0 :(得分:13)

您可以简单地在您的原生模块中添加模拟:

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

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

答案 1 :(得分:2)

通过这种方式,你将模拟它一次(在开始玩笑之前)

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

不要忘记在YourNativeBridge

中模拟所有可能的功能,属性

答案 2 :(得分:1)

Jest是一个JavaScript测试工具,它不会运行您在本机模块中使用Objective C / Swift / Java编写的代码。您可以模拟本机模块的功能,以便您可以通过链接的方法从JavaScript调用它。例如

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

答案 3 :(得分:0)

#__mocks__/react-native-modules

const ReactNative = require('react-native')

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

module.exports = ReactNative

然后

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

答案 4 :(得分:0)

这对我也失败了(本机0.57.5,开玩笑23.6.0)。我能够找到一个解决方案,但它与这里完全不同(就我而言,是一种更优雅的解决方案)。

查看the ticket I filed了解更多详细信息。

从本质上讲,我必须通过作为第二个参数传递给jest.mock()的函数来充实NativeModules,并将其放在使用Jest的setupFiles config选项在每次测试开始时运行的脚本中。