了解如何在 Expo 模块中模拟原生调用。
为 Expo 项目编写单元测试的推荐方法是使用 Jest 和 jest-expo
预设。
¥The recommended way to write unit tests for an Expo project is to use Jest and the jest-expo
preset.
要为使用原生代码的应用编写单元测试,你需要模拟原生调用。术语“模拟”意味着用不执行任何操作的虚假版本替换函数的实际实现。此方法对于在本地计算机上运行单元测试非常有用,因为它涉及绕过对仅在设备上可用的原生代码的需求,并且调用本地计算机上的原生函数的任何代码都将不起作用。
¥To write a unit test for an app that uses native code, you need to mock native calls. The term Mocking means to replace the actual implementation of a function with a fake version that does not perform any actions. This approach is useful for running unit tests on a local computer as it involves bypassing the need for native code which is only available on a device, and any code that calls native functions on a local machine will not work.
Expo SDK 包含针对我们每个社区包的一组默认模拟。你还可以使用内置 Jest API(例如 模拟函数)自行模拟任何 JS 代码。
¥Expo SDK includes a set of default mocks for each of our community packages. You can also mock any JS code yourself using built-in Jest APIs such as mock functions.
但是,为了在你的 Expo 模块中提供默认模拟,我们提供了一种打包它们的方法。这确保了当你的模块用户运行单元测试时,他们将自动使用模拟的实现。
¥However, to provide default mocks in your Expo Module, we offer a method to bundle them. This ensures that when your module user runs unit tests, they will automatically use a mocked implementation.
¥Providing mocks for a module
创建一个与要模拟的原生模块同名的文件,并将其放置在模块的模拟目录中。确保从此文件导出模拟实现。在单元测试期间运行时,由于 requireNativeModule
调用,jest-expo
预设将自动返回导出的函数。
¥Create a file with the same name as the native module you want to mock and place it in your module's mocks directory. Make sure to export the mock implementation from this file.
The jest-expo
preset will automatically return the exported functions because of a requireNativeModule
call when running during a unit test.
例如,expo-clipboard
库有一个名为 ExpoClipboard
的原生模块。你将在 mocks 目录中创建一个 ExpoClipboard.ts 来模拟它。
¥For example, the expo-clipboard
library has a native module called ExpoClipboard
. You will create a ExpoClipboard.ts in the mocks directory to mock it.
export async function hasStringAsync(): Promise<boolean> {
return false;
}
现在,在单元测试中,调用 ExpoClipboard.hasStringAsync()
将返回 false
。
¥Now, in a unit test, calling ExpoClipboard.hasStringAsync()
returns false
.
¥Automatic generation of mocks
如果原生模块有多个方法,则维护原生模块的模拟可能会是一项繁重的工作。为了使这更容易,我们提供了一个脚本,可以自动为模块中的所有原生函数生成模拟。它适用于根据模块中的 Swift 实现生成 TypeScript 和 JavaScript 中的模拟。
¥Maintaining mocks for native modules can be a lot of work if the native module has multiple methods. To make this easier, we provide a script that automatically generates mocks for all native functions in a module. It works for generating mocks in TypeScript and JavaScript based on the Swift implementation in your module.
要使用此脚本,你必须安装 SourceKitten 框架并在模块中运行 generate-ts-mocks
命令。
¥To use this script, you have to install SourceKitten framework and run the generate-ts-mocks
command in your module.
-
brew install sourcekitten
-
npx expo-modules-test-core generate-ts-mocks
上面的命令会在模块的 mocks 目录中生成 ExpoModuleName.ts。它包含模块中每个原生方法和视图的模拟实现。
¥The command above generates ExpoModuleName.ts in the mocks directory of your module. It contains a mock implementation for each native method and view in your module.
提示:你还可以运行
generate-js-mocks
以在 JavaScript 中生成模拟。¥Tip: You can also run
generate-js-mocks
to generate mocks in JavaScript.
¥More
了解如何设置和配置 jest-expo 包以编写项目单元和快照测试。