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

GraphQL+Node.js项目Jest环境销毁报错,使用fakeTimers仍未解决

解决Jest环境销毁后导入文件的ReferenceError问题

针对你遇到的ReferenceError: You are trying to import a file after the Jest environment has been torn down问题,结合Apollo Server测试场景,提供以下可行解决思路:

方案1:测试后主动关闭Apollo Server实例

Apollo Server创建后可能残留异步资源(如数据库连接、隐式定时器),导致Jest销毁环境后仍有代码执行。测试完成后主动关闭服务器可避免这类问题:

修改office.test.ts:

import {ApolloServer} from 'apollo-server'
import {expect, test, jest} from '@jest/globals';
import officeGql from '../controllers/controller'

// 移除重复的jest.useFakeTimers(),已全局启用无需重复调用
test('Office Module Test', async () => {
  const typeDefs = officeGql.types
  const resolvers = officeGql.resolvers
  const testServer = new ApolloServer({
    typeDefs,
    resolvers,
  });

  // 修正GraphQL查询语法错误:字段需嵌套在offices下
  const response = await testServer.executeOperation({
    query: `query offices($limit: Int, $offset: Int){
      offices(limit: $limit,offset: $offset){
        name, address
      }
    }`,
    variables: { limit: 10, offset:0 },
  });

  expect(response.data).toBeTruthy();
  // 测试结束后关闭服务器
  await testServer.stop();
});

方案2:隔离模块导入,避免提前执行定时器代码

如果officeGql模块在导入阶段就执行了依赖定时器的代码,会导致Jest环境未就绪时触发异常。用jest.isolateModules()包裹导入操作,确保代码在测试上下文内执行:

import {ApolloServer} from 'apollo-server'
import {expect, test, jest} from '@jest/globals';

test('Office Module Test', async () => {
  let officeGql;
  // 隔离模块导入,避免在测试外执行初始化代码
  jest.isolateModules(() => {
    officeGql = require('../controllers/controller').default;
  });

  const typeDefs = officeGql.types
  const resolvers = officeGql.resolvers
  const testServer = new ApolloServer({
    typeDefs,
    resolvers,
  });

  const response = await testServer.executeOperation({
    query: `query offices($limit: Int, $offset: Int){
      offices(limit: $limit,offset: $offset){
        name, address
      }
    }`,
    variables: { limit: 10, offset:0 },
  });

  expect(response.data).toBeTruthy();
  await testServer.stop();
});

方案3:添加全局Jest清理逻辑

在Jest配置中新增全局setup文件,统一清理定时器和模块缓存:

修改jest.config.ts:

import type { Config } from "@jest/types"
const config: Config.InitialOptions = {
    transform: {
        '^.+\\.tsx?$': 'ts-jest'
    },
    testRegex: '(/__test__/.*|(\\.|/)(test|spec))\\.[jt]sx?$',
    moduleFileExtensions: [ 'js','ts'],
    testEnvironment: "jest-environment-node",
    fakeTimers: {
        enableGlobally: true,
      },
    // 新增全局setup文件
    setupFilesAfterEnv: ['./jest.setup.ts'],
    verbose: true
}
export default config

新建jest.setup.ts:

import { jest } from '@jest/globals';

afterEach(() => {
  // 清理所有定时器
  jest.clearAllTimers();
  // 重置模块缓存,避免跨测试污染
  jest.resetModules();
});

方案4:解决全局与局部fakeTimers冲突

已在jest.config.ts中全局启用fakeTimers,无需在测试文件中重复调用jest.useFakeTimers(),重复操作会导致定时器状态混乱,直接移除测试文件中的该语句即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:55:13