- Getting Started
- Using Matchers
- Testing Asynchronous Code
- Setup and Teardown
- Mock Functions
- Jest Platform
- Jest Community
- More Resources
- Snapshot Testing
- An Async Example
- Timer Mocks
- Manual Mocks
- ES6 Class Mocks
- Bypassing module mocks
- Using with webpack
- Using with puppeteer
- Using with MongoDB
- Using with DynamoDB
- DOM Manipulation
- Watch Plugins
- Migrating to Jest
- Troubleshooting
- Architecture
- Testing React Apps
- Testing React Native Apps
- Testing Web Frameworks
- Expect
- Mock Functions
- The Jest Object
- Configuring Jest
- Jest CLI Options
- Globals
Testing React Native Apps
At Facebook, we use Jest to test React Native applications.
阅读以下系列文章来深入了解如何使用 Jest 测试一个真实的 React Native 示例应用:第一篇: Jest – Snapshot come into play 和 第二篇: Jest – Redux Snapshots for your Actions and Reducers.
安装
Starting from react-native version 0.38, a Jest setup is included by default when running react-native init
. The following configuration should be automatically added to your package.json file:
// package.json
"scripts": {
"test": "jest"
},
"jest": {
"preset": "react-native"
}
Note: If you are upgrading your react-native application and previously used the jest-react-native
preset, remove the dependency from your package.json
file and change the preset to react-native
instead.
用 yarn test
来运行 Jest 测试。
Snapshot Test
下面来为一个入门的小型组件创建一个快照测试,它的内部有些View、Text组件和一些样式:
// Intro.js
import React, {Component} from 'react';
import {StyleSheet, Text, View} from 'react-native';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: '#F5FCFF',
flex: 1,
justifyContent: 'center',
},
instructions: {
color: '#333333',
marginBottom: 5,
textAlign: 'center',
},
welcome: {
fontSize: 20,
margin: 10,
textAlign: 'center',
},
});
export default class Intro extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>
这是一个 React Native 快照测试。
</Text>
</View>
);
}
}
现在,使用React的test renderer和Jest的快照特性来和组件交互,获得渲染结果和生成快照文件:
// __tests__/Intro-test.js
import React from 'react';
import Intro from '../Intro';
import renderer from 'react-test-renderer';
test('renders correctly', () => {
const tree = renderer.create(<Intro />).toJSON();
expect(tree).toMatchSnapshot();
});
当你运行 npm test
或者 jest
,将产生一个像下面的文件:
// __tests__/__snapshots__/Intro-test.js.snap
exports[`Intro renders correctly 1`] = `
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#F5FCFF",
"flex": 1,
"justifyContent": "center",
}
}>
<Text
style={
Object {
"fontSize": 20,
"margin": 10,
"textAlign": "center",
}
}>
Welcome to React Native!
</Text>
<Text
style={
Object {
"color": "#333333",
"marginBottom": 5,
"textAlign": "center",
}
}>
This is a React Native snapshot test.
</Text>
</View>
`;
下次你运行测试时,渲染的结果将会和之前创建的快照进行比较。 代码变动时快照必须按顺序提交。 当快照测试失败,你需要去检查是否是你想要或不想要的变动。 如果变动符合预期,你可以通过jest -u
调用Jest从而重写存在的快照。
示例代码可在 examples/enzyme 找到。
Preset configuration
The preset sets up the environment and is very opinionated and based on what we found to be useful at Facebook. All of the configuration options can be overwritten just as they can be customized when no preset is used.
Environment
react-native
ships with a Jest preset, so the jest.preset
field of your package.json
should point to react-native
. The preset is a node environment that mimics the environment of a React Native app. Because it doesn't load any DOM or browser APIs, it greatly improves Jest's startup time.
transformIgnorePatterns customization
transformignorepatterns
选项可用于创建用于 Babel 的黑白名单。 Many react-native npm modules unfortunately don't pre-compile their source code before publishing.
By default the jest-react-native preset only processes the project's own source files and react-native. If you have npm dependencies that have to be transformed you can customize this configuration option by whitelisting modules other than react-native:
"transformIgnorePatterns": [
"node_modules/(?!(react-native|my-project|react-native-button)/)"
]
setupFiles
If you'd like to provide additional configuration for every test file, the setupFiles
configuration option can be used to specify setup scripts.
moduleNameMapper
The moduleNameMapper
can be used to map a module path to a different module. By default the preset maps all images to an image stub module but if a module cannot be found this configuration option can help:
"moduleNameMapper": {
"my-module.js": "<rootDir>/path/to/my-module.js"
}
Tips
Mock native modules using jest.mock
The Jest preset built into react-native
comes with a few default mocks that are applied on a react-native repository. However some react-native components or third party components rely on native code to be rendered. In such cases, Jest's manual mocking system can help to mock out the underlying implementation.
For example, if your code depends on a third party native video component called react-native-video
you might want to stub it out with a manual mock like this:
jest.mock('react-native-video', () => 'Video');
This will render the component as <Video {...props} />
with all of its props in the snapshot output. 想了解更多还可以阅读 caveats around Enzyme and React 16.
Sometimes you need to provide a more complex manual mock. For example if you'd like to forward the prop types or static fields of a native component to a mock, you can return a different React component from a mock through this helper from jest-react-native:
jest.mock('path/to/MyNativeComponent', () => {
const mockComponent = require('react-native/jest/mockComponent');
return mockComponent('path/to/MyNativeComponent');
});
Or if you'd like to create your own manual mock, you can do something like this:
jest.mock('Text', () => {
const RealComponent = jest.requireActual('Text');
const React = require('React');
class Text extends React.Component {
render() {
return React.createElement('Text', this.props, this.props.children);
}
}
Text.propTypes = RealComponent.propTypes;
return Text;
});
In other cases you may want to mock a native module that isn't a React component. The same technique can be applied. We recommend inspecting the native module's source code and logging the module when running a react native app on a real device and then modeling a manual mock after the real module.
If you end up mocking the same modules over and over it is recommended to define these mocks in a separate file and add it to the list of setupFiles
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论