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

React Native测试Tab Navigator报mockConstructor无渲染返回错误

报错根因

触发Nothing was returned from render报错的核心原因是你对@react-navigation/native做了全量手动mock,把模块内所有导出(包括NavigationContainer、createBottomTabNavigator、createStackNavigator等核心组件和方法)全部替换成了无返回值的空jest.fn()。
React要求所有组件渲染时必须返回合法JSX节点或者null,空jest.fn()默认返回undefined,完全不符合组件渲染规则,直接导致渲染中断抛错。
除此之外,你对其他原生依赖(@react-native-masked-view/masked-view、react-native-maps、react-native-pdf等)的mock也都是空jest.fn(),即便解决导航模块的mock问题,这些模块的mock同样会触发同类渲染报错。

修复步骤
    1. 删除测试文件中手动编写的@react-navigation/native全量mock代码块,不要手动mock整个React Navigation的JS层逻辑,会直接破坏导航的Context依赖和组件渲染逻辑。
    1. 调整Jest配置,加入对React Navigation相关模块的转译支持,避免node_modules内的导航ES模块代码无法被Jest识别:
// jest.config.js 配置示例
module.exports = {
  preset: '@testing-library/react-native',
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
  transformIgnorePatterns: [
    'node_modules/(?!(react-native|@react-native|@react-navigation|@react-native-masked-view/masked-view)/)'
  ]
}
    1. 修正所有原生模块的mock写法,确保所有被mock的组件导出都返回合法的可渲染节点,不要使用空jest.fn():
// 修正后的原生依赖mock示例
jest.mock('@react-native-masked-view/masked-view', () => ({
  MaskedView: ({ children }) => children,
}));

jest.mock('@invertase/react-native-apple-authentication', () => ({
  appleAuth: {
    isSupported: jest.fn(() => Promise.resolve(false)),
    performRequest: jest.fn(() => Promise.resolve({})),
  },
}));

jest.mock('react-native-maps', () => {
  const { View } = require('react-native');
  return {
    MapView: (props) => <View {...props} testID="map-view" />,
    Marker: (props) => <View {...props} />,
  }
});

jest.mock('react-native-pdf', () => {
  const { View } = require('react-native');
  return {
    Pdf: (props) => <View {...props} testID="pdf-view" />,
  }
});
    1. 修正测试用例的渲染逻辑,React Navigation的测试环境已经内置了必要的NavigationContainer上下文,不需要你在测试用例里手动嵌套包裹,直接渲染根导航组件即可:
import { render, screen } from '@testing-library/react-native';
import { RootStack } from '../index';

describe('Testing react navigation', () => {
  test('screen contains a button linking to the notifications page', async () => {
    render(<RootStack />);
    // 后续在这里添加你的断言逻辑,比如校验底部Tab元素是否存在
    // expect(screen.getByRole('button', { name: '通知' })).toBeTruthy();
  });
});

注意:测试React Navigation相关逻辑时,仅需要mock无法在Jest/jsdom环境运行的原生底层模块,不要mock导航库本身的JS层导出,否则会彻底破坏导航的运行逻辑。

内容的提问来源于stack exchange,提问作者Thor0o0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:51:27