Jest+TypeScript运行快照测试时expo-apple-authentication报TypeError
报错根因
测试运行在Node.js环境,无iOS原生运行时支撑,expo-apple-authentication引入的原生按钮组件调用requireNativeViewManager时,拿不到对应原生模块的配置参数,对undefined值调用includes方法直接抛出类型错误。
解决步骤
- 给
expo-apple-authentication添加Jest mock
在项目根目录(和node_modules同级)的__mocks__文件夹下新建expo-apple-authentication.ts文件,写入以下mock代码,覆盖模块所有对外导出的方法、组件和枚举值:
- 给
import React from "react"; import { TouchableOpacity, Text } from "react-native"; export const AppleAuthenticationButton = ({ onPress, ...rest }: any) => ( <TouchableOpacity onPress={onPress} testID="apple-signin-btn" {...rest}> <Text>Sign in with Apple</Text> </TouchableOpacity> ); export const AppleAuthenticationButtonType = { SIGN_IN: 0, CONTINUE: 1, SIGN_UP: 2, }; export const AppleAuthenticationButtonStyle = { WHITE: 0, WHITE_OUTLINE: 1, BLACK: 2, }; export const AppleAuthenticationScope = { FULL_NAME: 0, EMAIL: 1, }; export const AppleAuthenticationCredentialState = { REVOKED: 0, AUTHORIZED: 1, NOT_FOUND: 2, TRANSFERRED: 3, }; export const isAvailableAsync = jest.fn(() => Promise.resolve(true)); export const signInAsync = jest.fn(() => Promise.resolve({ identityToken: "mock-token", user: "mock-user-123", email: "test@mock.com", fullName: { givenName: "Test", familyName: "User" }, }) ); export const getCredentialStateAsync = jest.fn(() => Promise.resolve(AppleAuthenticationCredentialState.AUTHORIZED) ); export default { AppleAuthenticationButton, AppleAuthenticationButtonType, AppleAuthenticationButtonStyle, AppleAuthenticationScope, AppleAuthenticationCredentialState, isAvailableAsync, signInAsync, getCredentialStateAsync, };
- 在测试初始化文件中启用mock
打开你现有的components/utils/jestSetup.ts文件,添加一行代码启用上述mock:
- 在测试初始化文件中启用mock
jest.mock("expo-apple-authentication");
- 清理Jest缓存后重新运行测试
执行命令清除旧的Jest缓存,避免旧的转译结果干扰:
- 清理Jest缓存后重新运行测试
npx jest --clearCache
可选快速修复方案
如果不需要对苹果登录逻辑做细粒度测试,也可以直接在jestSetup.ts中mock出问题的底层原生适配器,跳过原生视图加载逻辑:
jest.mock("@unimodules/react-native-adapter", () => ({ requireNativeViewManager: jest.fn(() => "MockedNativeView"), }));
注意:你当前的
jest.config.js已经正确配置了transformIgnorePatterns,包含了@unimodules和expo相关的转译规则,不需要额外修改配置。
内容的提问来源于stack exchange,提问作者Neelkanth Tandel
相关产品推荐
相关产品推荐

