Unit testing React-Native中的非组件单元测试
我想为React Native/TypeScript应用程序编写一些单元测试。问题是有些库不在开发环境下运行,比如“AsyncStorage”或“react-native-sqlite-2” 我在Jest网站上发现的唯一一件事是关于模拟,但这只是一种分离UI测试的方法 我正在考虑使用一些node.js库来模拟这些库,根据环境加载正确的库 比如:Unit testing React-Native中的非组件单元测试,unit-testing,react-native,Unit Testing,React Native,我想为React Native/TypeScript应用程序编写一些单元测试。问题是有些库不在开发环境下运行,比如“AsyncStorage”或“react-native-sqlite-2” 我在Jest网站上发现的唯一一件事是关于模拟,但这只是一种分离UI测试的方法 我正在考虑使用一些node.js库来模拟这些库,根据环境加载正确的库 比如: if(isDevelopment) { SQLiteDatabase = require("./sqlite_database_node").S
if(isDevelopment) {
SQLiteDatabase = require("./sqlite_database_node").SQLiteDatabaseNode;
}
else {
SQLiteDatabase = require("./sqlite_database_rn").SQLiteDatabaseRN;
}
这是解决这个问题的正确方法吗?如果是,我如何导入/要求它工作?如果没有,最好的方法是什么?当您运行Jest或任何单元测试时。测试正在节点环境上运行。 因此,当您尝试访问具有本机组件/库(例如:异步存储或SQLite)的模块时,代码将在测试环境中中断 为了解决这个问题,Jest提出了模块模拟。 所以我在我的项目中所做的是,对于我使用的任何在内部使用本机模块的node_模块。。我为它创建了一个全局模拟 要做到这一点,您只需在根目录上创建一个文件夹
\uuuuu mocks\uuuu
,如下所示
.
├── README.md
├── __mocks__
│ ├── base-64.js
│ ├── react-native-animatable.js
│ ├── react-native-config.js
│ ├── react-native-device-info.js
│ ├── react-native-fetch-blob.js
│ ├── react-native-firebase.js
│ ├── react-native-google-analytics-bridge.js
│ ├── react-native-map-markerclustering.js
│ ├── react-native-maps.js
│ ├── react-native-simple-download-manager.js
│ ├── react-native-simple-toast.js
│ ├── react-native-splash-screen.js
│ ├── react-native-testfairy.js
│ ├── react-native-version-number.js
│ └── react-native.js
├── __tests__
│ └── index.test.js
├── app
│ ├── App.container.js
│ ├── __tests__
│ ├── assets
│ ├── components
│ ├── config
│ ├── index.js
│ ├── language
│ ├── pages
│ ├── redux
│ ├── routes
│ ├── themes
│ └── utils
├── app.json
├── circle.yml
├── index.js
├── package.json
└── yarn.lock
作为一个例子,让我们看看
\uuuu mocks\uuuu/react native firebase.js
module.exports = {
crash: () => ({
setCrashCollectionEnabled: jest.fn()
}),
auth: () => ({
signInAnonymously: jest.fn()
}),
database: () => ({
ref: () => ({
on: jest.fn()
})
}),
config: () => ({
fetch: jest.fn(),
setDefaults: jest.fn(),
getValue: jest.fn()
}),
messaging: jest.fn(() => ({
requestPermissions: jest.fn(),
subscribeToTopic: jest.fn(),
getToken: jest.fn(Promise.resolve),
onMessage: jest.fn(),
getInitialNotification: jest.fn(Promise.resolve),
onTokenRefresh: jest.fn()
}))
};
或者您可能\uuuu mocks\uuuu/react native device info
const mockmod=jest.genMockFromModule('react-native-device-info');
module.exports=mockmod;
重点是。。在测试期间,当您执行require('react-native-device-info')
因此,在test env u中将运行一个模拟模块,而在app env中,您将拥有实际的节点模块。当您运行Jest或任何单元测试时。测试正在节点环境上运行。 因此,当您尝试访问具有本机组件/库(例如:异步存储或SQLite)的模块时,代码将在测试环境中中断 为了解决这个问题,Jest提出了模块模拟。 所以我在我的项目中所做的是,对于我使用的任何在内部使用本机模块的node_模块。。我为它创建了一个全局模拟 要做到这一点,您只需在根目录上创建一个文件夹
\uuuuu mocks\uuuu
,如下所示
.
├── README.md
├── __mocks__
│ ├── base-64.js
│ ├── react-native-animatable.js
│ ├── react-native-config.js
│ ├── react-native-device-info.js
│ ├── react-native-fetch-blob.js
│ ├── react-native-firebase.js
│ ├── react-native-google-analytics-bridge.js
│ ├── react-native-map-markerclustering.js
│ ├── react-native-maps.js
│ ├── react-native-simple-download-manager.js
│ ├── react-native-simple-toast.js
│ ├── react-native-splash-screen.js
│ ├── react-native-testfairy.js
│ ├── react-native-version-number.js
│ └── react-native.js
├── __tests__
│ └── index.test.js
├── app
│ ├── App.container.js
│ ├── __tests__
│ ├── assets
│ ├── components
│ ├── config
│ ├── index.js
│ ├── language
│ ├── pages
│ ├── redux
│ ├── routes
│ ├── themes
│ └── utils
├── app.json
├── circle.yml
├── index.js
├── package.json
└── yarn.lock
作为一个例子,让我们看看
\uuuu mocks\uuuu/react native firebase.js
module.exports = {
crash: () => ({
setCrashCollectionEnabled: jest.fn()
}),
auth: () => ({
signInAnonymously: jest.fn()
}),
database: () => ({
ref: () => ({
on: jest.fn()
})
}),
config: () => ({
fetch: jest.fn(),
setDefaults: jest.fn(),
getValue: jest.fn()
}),
messaging: jest.fn(() => ({
requestPermissions: jest.fn(),
subscribeToTopic: jest.fn(),
getToken: jest.fn(Promise.resolve),
onMessage: jest.fn(),
getInitialNotification: jest.fn(Promise.resolve),
onTokenRefresh: jest.fn()
}))
};
或者您可能\uuuu mocks\uuuu/react native device info
const mockmod=jest.genMockFromModule('react-native-device-info');
module.exports=mockmod;
重点是。。在测试期间,当您执行require('react-native-device-info')
因此,在test env u中将运行一个模拟模块,而在app env中,您将拥有实际的节点模块。如果您有纯单元测试,而这些测试不涉及React本机组件中的代码,那么您为什么需要模拟任何东西。如果有人在独立于react-native(如域层)的JS模块上编写单元测试,而react-native位于react-native项目的下面,那么应该能够在没有任何本机依赖的情况下对裸露的JS逻辑进行单元测试。你会怎么安排?现在,如果我尝试运行单元测试,这些测试只是功能测试,而不是在react组件上,我仍然会得到“不变冲突:本机模块不能为null”,我同意,我已经花了两周的时间评估react native,尽管它在组件级别带来了诸多好处,但实际上构建一个正确分层的大型应用程序,并且单独测试这些分层是一件非常痛苦的事情。在这一点上,我的印象是,即使是大型的react原生项目也只是在进行e2e测试后才进行模拟和测试,对于大型团队来说,这可能没问题,但是当试图与5-6人一起工作时,几乎没有保证较低的层在react本机环境中工作会很糟糕。如果您有纯单元测试,而这些测试不涉及react本机组件中的代码,那么您为什么需要模拟任何东西呢。如果有人在独立于react-native(如域层)的JS模块上编写单元测试,而react-native位于react-native项目的下面,那么应该能够在没有任何本机依赖的情况下对裸露的JS逻辑进行单元测试。你会怎么安排?现在,如果我尝试运行单元测试,这些测试只是功能测试,而不是在react组件上,我仍然会得到“不变冲突:本机模块不能为null”,我同意,我已经花了两周的时间评估react native,尽管它在组件级别带来了诸多好处,但实际上构建一个正确分层的大型应用程序,并且单独测试这些分层是一件非常痛苦的事情。在这一点上,我的印象是,即使是大型react本机项目,也只是在进行e2e测试后才进行模拟和测试,对于大型团队来说,这可能没什么问题,但当试图与5-6人一起工作时,几乎没有任何保证,在react本机环境下,较低的层将工作,这是一个严重的问题。