You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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,避免每个测试文件重复写包裹逻辑:

  1. 打开你的jest配置文件jest.config.js,添加如下配置:
module.exports = {
  // 其余配置不变
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}
  1. 在项目根目录新建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ć

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 23:00:04