使用react-native-safe-area-context测试组件时出现报错如何解决?
报错原因
- 单元测试为组件独立测试场景,不会加载你应用入口处配置的顶层
SafeAreaProvider,因此CeoHeader内部调用的安全区域相关hook/组件无法获取到上下文值,触发报错。 - 你引入的官方jest mock在部分版本的
react-native-safe-area-context中存在兼容性问题,不会自动为测试组件注入上下文,需要额外配置。
解决方法
方法1:测试时手动包裹Provider
直接在测试代码渲染被测组件时,外层套上mock库导出的SafeAreaProvider即可,修改测试用例如下:
import _ from "lodash" import React from "react" import mockSafeAreaContext, { SafeAreaProvider } from "react-native-safe-area-context/jest/mock" import renderer from "react-test-renderer" import CeoHeader from "../../src/screens/assessment/board/ceo_review/header" jest.mock("react-native-safe-area-context", () => mockSafeAreaContext) let props beforeEach(() => { props = { onBack: jest.fn(), firstOrLastPage: _.sample([true, false]), onRefresh: jest.fn(), } }) describe("<CeoHeader />", () => { it("has 1 child", () => { const tree = renderer.create( <SafeAreaProvider> <CeoHeader {...props} /> </SafeAreaProvider> ).toJSON() expect(tree.children).toHaveLength(1) }) })
方法2:手动mock安全区域相关能力
如果官方mock存在兼容性问题,可以替换为手动mock,直接固定返回安全区域数值:
import _ from "lodash" import React from "react" import renderer from "react-test-renderer" import CeoHeader from "../../src/screens/assessment/board/ceo_review/header" jest.mock("react-native-safe-area-context", () => ({ ...jest.requireActual("react-native-safe-area-context"), useSafeAreaInsets: () => ({ top: 0, left: 0, right: 0, bottom: 0 }), SafeAreaView: ({ children }) => <>{children}</>, SafeAreaProvider: ({ children }) => <>{children}</>, })) // 其余代码保持不变
方法3:全局配置测试上下文(推荐)
如果有多个组件测试都依赖安全区域能力,可以在jest全局配置文件中统一注入mock的Provider,避免每个测试文件重复写包裹逻辑:
- 打开你的jest配置文件
jest.config.js,添加如下配置:
module.exports = { // 其余配置不变 setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], }
- 在项目根目录新建
jest.setup.js,如果用@testing-library/react-native可以配置默认wrapper:
import { SafeAreaProvider } from 'react-native-safe-area-context'; import { render } from '@testing-library/react-native'; global.render = (ui, options) => render(ui, { wrapper: SafeAreaProvider, ...options });
之后所有测试用global.render方法渲染组件都会自动带上SafeAreaProvider。
内容的提问来源于stack exchange,提问作者Filip Račić
相关产品推荐
相关产品推荐

