依赖项更新
步骤6: 测试更新
6.1 更新jest.config.js
transformIgnorePatterns须包含@amazon-devices/react-native-kepler。程序包4.0.0会在its jest/setup.js文件中使用ES模块语法。如果不采用此模式,Jest文件会报错SyntaxError: 无法在模块外使用导入语句。
module.exports = {
preset: 'react-native',
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?|@amazon-devices/react-native-kepler)|react-native-safe-area-context)',
],
};
6.2 为电视模拟创建jest.setup.js
RN 0.83更改了模拟在测试环境中的工作方式。创建一个包含TV适用模拟的设置文件,如下例所示。
// jest.setup.js
/**
* 为电视平台模拟Dimensions API
* Fire TV设备的分辨率达到1920x1080(全高清),比例系数为1
*/
jest.mock('react-native/Libraries/Utilities/Dimensions', () => ({
get: jest.fn().mockReturnValue({
width: 1920,
height: 1080,
scale: 1,
fontScale: 1,
}),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
}));
/**
* 为电视平台模拟PixelRatio API
* 电视设备使用的比例系数为1(无像素倍增)
*/
jest.mock('react-native/Libraries/Utilities/PixelRatio', () => ({
default: {
get: jest.fn().mockReturnValue(1),
getFontScale: jest.fn().mockReturnValue(1),
getPixelSizeForLayoutSize: jest.fn((layoutSize) => layoutSize),
roundToNearestPixel: jest.fn((layoutSize) => layoutSize),
},
}));
/**
* 模拟NativeAnimatedModule — RN 0.83会调用23种特定方法。
* 任何触发导航动画的测试均为必填项。
*/
jest.mock('react-native/Libraries/Animated/NativeAnimatedModule', () => ({
__esModule: true,
default: {
startOperationBatch: jest.fn(),
finishOperationBatch: jest.fn(),
createAnimatedNode: jest.fn(),
updateAnimatedNodeConfig: jest.fn(),
getValue: jest.fn(),
startListeningToAnimatedNodeValue: jest.fn(),
stopListeningToAnimatedNodeValue: jest.fn(),
connectAnimatedNodes: jest.fn(),
disconnectAnimatedNodes: jest.fn(),
startAnimatingNode: jest.fn(),
stopAnimation: jest.fn(),
setAnimatedNodeValue: jest.fn(),
setAnimatedNodeOffset: jest.fn(),
flattenAnimatedNodeOffset: jest.fn(),
extractAnimatedNodeOffset: jest.fn(),
connectAnimatedNodeToView: jest.fn(),
disconnectAnimatedNodeFromView: jest.fn(),
restoreDefaultValues: jest.fn(),
dropAnimatedNode: jest.fn(),
addAnimatedEventToView: jest.fn(),
removeAnimatedEventFromView: jest.fn(),
addListener: jest.fn(),
removeListeners: jest.fn(),
},
}));
6.3 为.default导出修复Jest模拟
RN 0.83为使用export default而更改了许多内部模块。现有的Jest模拟会返回不含.default属性的普通对象,该模拟会在静默状态下失败,导致组件在运行时收到undefined。
现象:多个测试套件报错无法读取undefined的属性(读取'create')。
受影响模块
react-native/Libraries/StyleSheet/StyleSheetreact-native/Libraries/StyleSheet/flattenStylereact-native/Libraries/EventEmitter/NativeEventEmitterreact-native/Libraries/Utilities/Platformreact-native/Libraries/Utilities/Dimensionsreact-native/Libraries/Utilities/PixelRatioreact-native/Libraries/Utilities/useWindowDimensionsreact-native/Libraries/BatchedBridge/NativeModules
修复对象类型导出模式
// ❌ 之前(RN 0.83中不可用)
jest.mock('react-native/Libraries/StyleSheet/StyleSheet', () => ({
create: (styles) => styles,
flatten: jest.fn(),
}));
//✅ 之后 — 包括__esModule和默认值
jest.mock('react-native/Libraries/StyleSheet/StyleSheet', () => {
const impl = {
create: (styles) => styles,
flatten: jest.fn(),
};
return { __esModule: true, default: impl, ...impl };
});
修复函数类型导出模式:
// 对于函数类型的default导出,直接返回该函数即可。
jest.mock('react-native/Libraries/StyleSheet/flattenStyle', () => {
const impl = jest.fn((style) => style);
return { __esModule: true, default: impl };
});
6.4 使用act()包装更新测试文件
React 19要求测试中的状态更新必须使用act()包装,如下例所示。
// ❌ 之前 (RN 0.72)
import 'react-native';
import React from 'react';
import App from '../App';
import renderer from 'react-test-renderer';
it('正确渲染', () => {
renderer.create(<App />);
});
// ✅ 之后 (RN 0.83) — 直接使用react-test-renderer
import React from 'react';
import ReactTestRenderer from 'react-test-renderer';
import App from '../App';
test('正确渲染', async () => {
await ReactTestRenderer.act(() => {
ReactTestRenderer.create(<App />);
});
});
@testing-library/react-native
如果使用@testing-library/react-native,则测试库会内部处理act()。请勿在ReactTestRenderer.act()中包装render(),否则会报错“测试渲染器未挂载,无法访问.root”。
// ✅ 正确操作是使用@testing-library/react-native
import { render, fireEvent } from '@testing-library/react-native';
test('正确渲染', () => {
const screen = render(<App />);
expect(screen).toMatchSnapshot();
});
test('处理按钮按下事件', () => {
const screen = render(<App />);
fireEvent.press(screen.getByTestId('myButton'));
expect(screen).toMatchSnapshot();
});
6.5 修复导航栈计时器泄漏问题
如果使用 react-navigation__stack,其Card.tsx文件中的动画setTimeout回调会在Jest拆除测试环境后触发。
现象:Jest环境拆除后,您试图导入文件
修复:添加到受影响的测试文件中
beforeEach(() => jest.useFakeTimers());
afterEach(() => {
jest.runOnlyPendingTimers();
jest.useRealTimers();
});
6.6 修复isolatedModules类型导出错误
如果TypeScript报错TS1205: 需使用 'export type',才能在启用 'isolatedModules' 时重新导出类型,请按下例更新您的导出类型。
// ❌ 之前
export { Cookie } from './types/CookieManagerTypes';
// ✅ 之后
export type { Cookie } from './types/CookieManagerTypes';
6.7 更新快照
修复所有测试问题后,重新生成快照。
# 运行测试以查看失败情况
npm test
# 更新所有快照
npm test -- -u
审查更改项。预期的React 19快照差异包括:
- 组件包装器结构更改
- 属性排序差异
- 文本节点渲染修改
- 异步边界更新
提交前使用git diff审查快照更改内容。
Last updated: 2026年7月9日

