Nestjs单元测试createTestingModule依赖注入

dan*_*ald 5 nomachine-nx typescript jestjs nestjs

我希望你能帮助我。\n我正在使用 Nx 和最新的 Angular/nestjs(日期:2 月 26 日)

\n
    ...\n    "@nestjs/common": "^7.0.0",\n    "@nestjs/config": "^0.6.3",\n    "@nestjs/core": "^7.0.0",\n    "@nestjs/platform-express": "^7.0.0",\n    "@nestjs/platform-socket.io": "^7.6.7",\n    "@nestjs/websockets": "^7.6.7",\n    "jest": "26.2.2",\n    "@nrwl/jest": "11.4.0",\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n

我无法使用 NestJS 和 Jest 运行单元测试\n我想测试以下服务:

\n
@Injectable()\nexport class CoreApiService {\n  logger = new Logger('CoreApiService');\n  apiEndpoint;\n\n  constructor(private httpService: HttpService, configService: ConfigService) {\n    this.apiEndpoint = configService.get('API_SERVICE_ENDPOINT');\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我收到以下错误:

\n
TypeError: Cannot read property 'get' of undefined\n\n
Run Code Online (Sandbox Code Playgroud)\n

所以看起来 ConfigService (还有 httpService)总是未定义的。

\n

当记录 httpService 和 ConfigService 时,它​​始终是未定义的。\n即使当我尝试实例化新实例时,new CoreApiService(new HttpService(), new ConfigService())\n我什至尝试过类似new CoreApiService({} as any, {get: (...params} => {return 'foo'})测试本身的操作

\n

它总是会出现上面提到的相同错误。

\n

测试文件:

\n
import { Test, TestingModule } from '@nestjs/testing';\nimport { CoreApiService } from './core-api.service';\nimport { ConfigModule, ConfigService } from '@nestjs/config';\nimport { HttpModule } from '@nestjs/common';\n\n\nclass ConfigServiceMock {\n  get(key: string): string {\n    switch (key) {\n      case 'API_SERVICE_ENDPOINT':\n        return '';\n    }\n  }\n}\n\ndescribe('CoreApiService', () => {\n  let module: TestingModule;\n  let service: CoreApiService;\n\n  beforeEach(async () => {\n    module = await Test.createTestingModule({\n      imports: [HttpModule, ConfigModule],\n      providers: [\n        CoreApiService,\n        { provide: ConfigService, useClass: ConfigServiceMock },\n      ],\n    }).compile();\n    service = module.get<CoreApiService>(CoreApiService);\n  });\n\n  it('should be defined', () => {\n    expect(service).toBeDefined();\n  });\n});\n\n\n
Run Code Online (Sandbox Code Playgroud)\n

我什至尝试过:.overrideProvider(ConfigService).useClass(ConfigServiceMock)

\n

先感谢您!

\n

编辑 03/01

\n

似乎模块本身的编译步骤失败了...\n因此对于当前测试文件,日志“COMPILED”将永远不会被执行。

\n
 CoreApiService \xe2\x80\xba should be defined\n\n    TypeError: Cannot read property 'get' of undefined\n\n      22 |\n      23 |   constructor(private httpService: HttpService, configService: ConfigService) {\n    > 24 |     this.apiEndpoint = configService.get('API_SERVICE_ENDPOINT');\n         |                                      ^\n      25 |   }\n      26 |\n      27 |   private static createRequestConfig(options: RequestHeader): RequestConfig {\n\n      at new CoreApiService (src/app/core-api/core-api.service.ts:24:38)\n      at Injector.instantiateClass (../../node_modules/@nestjs/core/injector/injector.js:286:19)\n      at callback (../../node_modules/@nestjs/core/injector/injector.js:42:41)\n      at Injector.resolveConstructorParams (../../node_modules/@nestjs/core/injector/injector.js:114:24)\n      at Injector.loadInstance (../../node_modules/@nestjs/core/injector/injector.js:46:9)\n      at Injector.loadProvider (../../node_modules/@nestjs/core/injector/injector.js:68:9)\n          at async Promise.all (index 5)\n      at InstanceLoader.createInstancesOfProviders (../../node_modules/@nestjs/core/injector/instance-loader.js:43:9)\n      at ../../node_modules/@nestjs/core/injector/instance-loader.js:28:13\n          at async Promise.all (index 1)\n      at InstanceLoader.createInstances (../../node_modules/@nestjs/core/injector/instance-loader.js:27:9)\n      at InstanceLoader.createInstancesOfDependencies (../../node_modules/@nestjs/core/injector/instance-loader.js:17:9)\n      at TestingModuleBuilder.compile (../../node_modules/@nestjs/testing/testing-module.builder.js:43:9)\n\n  \xe2\x97\x8f CoreApiService \xe2\x80\xba should be defined\n\n    expect(received).toBeDefined()\n\n    Received: undefined\n\n      44 |   it('should be defined', () => {\n      45 |     console.log('SHOULD BE DEFINED')\n    > 46 |     expect(service).toBeDefined();\n         |                     ^\n      47 |   });\n      48 | });\n      49 |\n\n      at Object.<anonymous> (src/app/core-api/core-api.service.spec.ts:46:21)\n
Run Code Online (Sandbox Code Playgroud)\n

当前的测试文件如下所示:

\n
import { Test, TestingModule } from '@nestjs/testing';\nimport { CoreApiService } from './core-api.service';\nimport { ConfigService } from '@nestjs/config';\nimport { HttpService, INestApplication } from '@nestjs/common';\n\nclass ConfigServiceMock {\n  get(key: string): string {\n    switch (key) {\n      case 'API_SERVICE_ENDPOINT':\n        return '';\n    }\n  }\n}\n\nclass HttpServiceMock {\n  get(): any {\n\n  }\n}\n\ndescribe('CoreApiService', () => {\n  let module: TestingModule;\n  let service: CoreApiService;\n  let app: INestApplication;\n\n  beforeEach(async () => {\n    console.log('beforeEach')\n    module = await Test.createTestingModule({\n      imports: [],\n      providers: [\n        { provide: ConfigService, useClass: ConfigServiceMock },\n        { provide: HttpService, useClass: HttpServiceMock },\n        CoreApiService,\n      ],\n    })\n      .compile();\n    console.log('COMPILED');\n    app = module.createNestApplication();\n    await app.init();\n    service = module.get<CoreApiService>(CoreApiService);\n  });\n\n  it('should be defined', () => {\n    console.log('SHOULD BE DEFINED')\n    expect(service).toBeDefined();\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

我也玩过提供者部分的顺序,但我想这不相关......

\n

lso*_*uza 1

您可能想尝试的两件事:

  1. 初始化您的 Nest 应用程序。在 中beforeEach,调用compile()模块后,添加以下行:
app = module.createNestApplication();
await app.init();
Run Code Online (Sandbox Code Playgroud)
  1. 不要ConfigModule在您的测试中导入。这将初始化实际的配置服务,您在模拟它时不需要它。