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

使用NestJS与Node测试运行器时E2E测试依赖注入失效问题

NestJS E2E测试中AppService注入失败问题解决思路

问题背景

使用NestJS和Node测试运行器搭建新项目时,单元测试可正常执行,但E2E测试抛出TypeError: Cannot read properties of undefined (reading 'getHello')错误。服务启动后可正常运行,仅E2E测试阶段出现依赖注入异常。

相关代码片段

Controller代码

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {
    console.log(appService)
  }

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Service代码

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Module代码

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

E2E测试代码

import { Test } from '@nestjs/testing';
import test from 'node:test';
import request from 'supertest';
import { INestApplication } from "@nestjs/common";
import * as assert from "assert";
import { AppModule } from "src/demo/app.module";

test.describe('AppController.getHello', () => {
  let app: INestApplication;

  test.before(async () => {
    const moduleFixture = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });
  test.after(async () => {
    await app.close();
  })

  test.it('should return "Hello World!"', async () => {
    await request(app.getHttpServer())
        .get('/')
        .then((response) => assert.strictEqual(response.body, 'Hello World!'))
  });
});

错误信息

执行测试命令glob ./**/*.test.ts -c 'tsx --test'时触发错误:

TypeError: Cannot read properties of undefined (reading 'getHello')
    at AppController.getHello (.../app.controller.ts:12:28)

解决思路

  • 调整测试钩子的异步逻辑:Node内置test模块的before钩子可能未正确等待NestJS测试模块初始化完成,替换为beforeEach确保每次测试前都完成模块初始化:

    test.beforeEach(async () => {
      const moduleFixture = await Test.createTestingModule({
        imports: [AppModule],
      }).compile();
    
      app = moduleFixture.createNestApplication();
      await app.init();
    });
    
  • 验证依赖注入容器状态:在测试模块编译后,手动检查容器中的服务实例是否存在,确认依赖注入流程正常:

    test.before(async () => {
      const moduleFixture = await Test.createTestingModule({
        imports: [AppModule],
      }).compile();
      
      // 打印服务实例,确认是否被正确注册
      const appService = moduleFixture.get(AppService);
      console.log('AppService instance:', appService);
    
      app = moduleFixture.createNestApplication();
      await app.init();
    });
    
  • 优化测试命令的文件匹配规则:避免glob命令同时匹配单元测试和E2E测试文件导致路径冲突,指定仅运行E2E测试文件:

    glob ./**/*.e2e-test.ts -c 'tsx --test'
    

    建议将E2E测试文件统一命名为*.e2e.test.ts,与单元测试文件区分开。

  • 检查模块导入路径:确认测试文件中AppModule的导入路径正确,避免相对路径错误导致模块未被加载:

    // 替换为项目中实际的相对路径
    import { AppModule } from '../app.module';
    
  • 升级NestJS版本:部分旧版本NestJS与Node内置测试模块存在兼容性问题,升级到最新稳定版本可解决此类问题:

    npm install @nestjs/core@latest @nestjs/common@latest @nestjs/testing@latest
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:46:25