如何使用 Jest 测试导入自定义原生模块的 React Native 组件?
Posted
技术标签:
【中文标题】如何使用 Jest 测试导入自定义原生模块的 React Native 组件?【英文标题】:How to test a React Native component that imports a custom native module with Jest? 【发布时间】:2017-05-11 10:26:27 【问题描述】:这是我尝试使用 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 类。
【问题讨论】:
【参考方案1】:这对我来说也失败了(react-native 0.57.5,jest 23.6.0)。我能够找到一个解决方案,但它与这里完全不同(在我的情况下,这是一个更优雅的解决方案)。
查看the ticket I filed了解更多详情。
本质上,我必须通过作为第二个参数传递给 jest.mock() 的函数来充实 NativeModules,并将其放在使用 Jest 的 setupFiles 配置选项在每次测试开始时运行的脚本中。
【讨论】:
【参考方案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
中所有可能的函数、属性
【讨论】:
有人写过这些属性的完整列表吗?我不确定我需要哪些,所以我想他们都会做【参考方案3】:#__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'
【讨论】:
这失败了:“无法设置属性 NativeModules of #【参考方案4】:你可以简单地在你的原生模块应该是的地方添加一个模拟:
import
NativeModules,
from 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
describe('TestProject', () =>
beforeEach(() =>
NativeModules.TestModule = test: jest.fn()
);
...
);
【讨论】:
谢谢!传递给beforeEach
的函数缺少一个右花括号,但在其他方面就像一个魅力。我还选择使用beforeAll
,因为这个设置只需要运行一次,而不是在每个规范之前运行。
太好了,我添加了缺少的花括号。
现在失败(0.57),因为您无法将属性添加到只读对象【参考方案5】:
Jest 是一个 javascript 测试工具,它不会在原生模块中运行你用 Objective C/Swift/Java 编写的代码。您可以模拟本机模块的功能,以便您可以通过链接到的方法从 JavaScript 调用它。例如。
jest.mock('NetInfo', () =>
return
isConnected:
fetch: () =>
return new Promise((accept, resolve) =>
accept(true);
)
);
【讨论】:
我认为这误解了我也有的问题。 OP 询问您如何模拟从react-native
导入的NativeModules.TestModule
。我被困住了,因为react-native
需要导入,而不是模拟,react-test-renderer
覆盖才能工作。
@rgoldfinger 是正确的。我不是在尝试测试本机模块本身,而是尝试模拟 NativeModules.TestModule
以测试 index.ios.js
。
有没有办法测试原生模块?以上是关于如何使用 Jest 测试导入自定义原生模块的 React Native 组件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Jest 测试中使用我的 webpack 的 html-loader 导入?
如何在 Jest 的自定义测试环境文件中使用 TypeScript?