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

React Native异步组件导致Jest测试失败的解决方法问询

React Native Jest测试报错:ReferenceError: 尝试在Jest环境销毁后导入文件

我给React Native项目的入口组件App.tsx写了基础测试用例,组件接收JSON格式的学生列表props,通过@react-navigation导航到HomeScreen,HomeScreen会调用带异步函数的Students组件。运行npm run test时出现错误:ReferenceError: You are trying to import a file after the Jest environment has been torn down,请问怎么让Jest等待App组件的子组件完成异步操作?


相关代码

App.tsx

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './Screens/HomeScreen';
import { StudentProps, RootStackParamList } from './types/StudentInfo';

export default function App(props: StudentProps): React.JSX.Element {
  const Stack = createNativeStackNavigator<RootStackParamList>();
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="ReactNative">
        <Stack.Screen
          name="ReactNative"
          component={HomeScreen}
          initialParams={{ studentList: props }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

App.test.tsx

import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import App from '../App';


test('renders correctly', () => {
  const tree = renderer
    .create(
      <App
        appList={[
          '{"name":"John Doe","course":"Jest"}',
          '{"name":"Jane Doe","course":"React Native"}'
        ]}
      />
    )
    .toJSON();
  expect(tree).toMatchSnapshot();
});

错误信息

> reactnativeproject@0.0.1 test
> jest


ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From __tests__/App.test.tsx.
      at Object.get BackHandler [as BackHandler] (node_modules/react-native/index.js:109:12)
      at node_modules/@react-navigation/native/lib/commonjs/useBackButton.js:50:37
      at commitHookEffectListMount (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12999:26)        
      at commitPassiveMountOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14422:11)        
      at commitPassiveMountEffects_complete (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14382:9)      at commitPassiveMountEffects_begin (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14369:7)   
      at commitPassiveMountEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14357:3)
      at flushPassiveEffectsImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16248:3)
      at flushPassiveEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16197:14)
      at node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16012:9
      at workLoop (node_modules/react-test-renderer/node_modules/scheduler/cjs/scheduler.development.js:266:34)
      at flushWork (node_modules/react-test-renderer/node_modules/scheduler/cjs/scheduler.development.js:239:14)
      at Immediate.performWorkUntilDeadline [as _onImmediate] (node_modules/react-test-renderer/node_modules/scheduler/cjs/scheduler.development.js:533:21)
  console.error
    The above error occurred in the <ForwardRef(NavigationContainerInner)> component:
    
        at NavigationContainerInner (C:\Github\bcgov\IAS\ReactNativeProject\node_modules\@react-navigation\native\src\NavigationContainer.tsx:107:23)
        at App
    
    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

      at logCapturedError (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8661:23)

解决方法

这个错误是因为Jest在测试结束后就销毁了运行环境,但子组件的异步操作还在执行,后续触发的代码尝试导入已被销毁环境中的模块导致的。可以通过以下几种方式解决:

1. 改用异步测试,等待渲染完成

React Test Renderer的act()方法可以确保所有状态更新和副作用都处理完毕后再继续测试,把测试改成异步函数即可:

import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import App from '../App';

test('renders correctly', async () => {
  let tree;
  await renderer.act(async () => {
    tree = renderer.create(
      <App
        appList={[
          '{"name":"John Doe","course":"Jest"}',
          '{"name":"Jane Doe","course":"React Native"}'
        ]}
      />
    );
  });
  expect(tree.toJSON()).toMatchSnapshot();
});

2. Mock导航容器和子组件的异步逻辑

如果测试只是验证App组件的结构和props传递,没必要渲染完整的导航栈和异步组件,直接Mock掉外部依赖更高效:

import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import App from '../App';
import { NavigationContainer } from '@react-navigation/native';

// Mock NavigationContainer,只渲染子元素
jest.mock('@react-navigation/native', () => ({
  NavigationContainer: ({ children }) => <div>{children}</div>,
}));

// Mock HomeScreen,返回占位组件
jest.mock('../Screens/HomeScreen', () => () => <div>HomeScreen</div>);

test('renders correctly', () => {
  const tree = renderer.create(
    <App
      appList={[
        '{"name":"John Doe","course":"Jest"}',
        '{"name":"Jane Doe","course":"React Native"}'
      ]}
    />
  ).toJSON();
  expect(tree).toMatchSnapshot();
});

3. 调整Jest配置,延迟环境销毁

如果前两种方法不适用,可以修改Jest配置,延长测试超时时间并延迟环境销毁:
在jest.config.js中添加:

module.exports = {
  // 保留原有配置,新增以下内容
  testTimeout: 10000, // 延长测试超时到10秒
  clearMocks: false, // 避免过早清除mock
};

同时在jest.setup.js中添加:

jest.useFakeTimers();
jest.runAllTimers();

不过这种是兜底方案,优先推荐前两种方法,尤其是Mock依赖的方式,测试速度更快也更稳定。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:10:54