简体   繁体   English

nestjs 单元测试 createTestingModule 依赖注入

[英]nestjs unit test createTestingModule Dependency Injection

I hope you can help me out.我希望你能帮助我。 I am using Nx with latest angular/nestjs (date: February, 26)我正在使用带有最新 angular/nestjs 的 Nx(日期:2 月 26 日)

    ...
    "@nestjs/common": "^7.0.0",
    "@nestjs/config": "^0.6.3",
    "@nestjs/core": "^7.0.0",
    "@nestjs/platform-express": "^7.0.0",
    "@nestjs/platform-socket.io": "^7.6.7",
    "@nestjs/websockets": "^7.6.7",
    "jest": "26.2.2",
    "@nrwl/jest": "11.4.0",
    ...

I cannot get my unit test running using NestJS with Jest I want to test following service:我无法使用带有 Jest 的 NestJS 运行单元测试我想测试以下服务:

@Injectable()
export class CoreApiService {
  logger = new Logger('CoreApiService');
  apiEndpoint;

  constructor(private httpService: HttpService, configService: ConfigService) {
    this.apiEndpoint = configService.get('API_SERVICE_ENDPOINT');
  }
}

and I get following error:我收到以下错误:

TypeError: Cannot read property 'get' of undefined

so it seems that the ConfigService (and also httpService) is always undefined.所以似乎 ConfigService(以及 httpService)总是未定义的。

when logging httpService and ConfigService, it will always be undefined.当记录 httpService 和 ConfigService 时,它总是未定义的。 Even when I try to instantiate new Instances like new CoreApiService(new HttpService(), new ConfigService()) I've even tried things like new CoreApiService({} as any, {get: (...params} => {return 'foo'}) in the test itself即使我尝试实例化new CoreApiService(new HttpService(), new ConfigService())类的新实例,我什至尝试过new CoreApiService({} as any, {get: (...params} => {return 'foo'})在测试本身

it will always be the same error mentioned above.它将始终是上述相同的错误。

The test file:测试文件:

import { Test, TestingModule } from '@nestjs/testing';
import { CoreApiService } from './core-api.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { HttpModule } from '@nestjs/common';


class ConfigServiceMock {
  get(key: string): string {
    switch (key) {
      case 'API_SERVICE_ENDPOINT':
        return '';
    }
  }
}

describe('CoreApiService', () => {
  let module: TestingModule;
  let service: CoreApiService;

  beforeEach(async () => {
    module = await Test.createTestingModule({
      imports: [HttpModule, ConfigModule],
      providers: [
        CoreApiService,
        { provide: ConfigService, useClass: ConfigServiceMock },
      ],
    }).compile();
    service = module.get<CoreApiService>(CoreApiService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });
});


I've even tried: .overrideProvider(ConfigService).useClass(ConfigServiceMock)我什至尝试过: .overrideProvider(ConfigService).useClass(ConfigServiceMock)

Thank you in advance!先感谢您!

Edit 03/01编辑 03/01

it seems that the compile step for the module itself fails... so for the current test file the log "COMPILED" will never be executed.似乎模块本身的编译步骤失败了......所以对于当前的测试文件,日志“COMPILED”将永远不会被执行。

 CoreApiService › should be defined

    TypeError: Cannot read property 'get' of undefined

      22 |
      23 |   constructor(private httpService: HttpService, configService: ConfigService) {
    > 24 |     this.apiEndpoint = configService.get('API_SERVICE_ENDPOINT');
         |                                      ^
      25 |   }
      26 |
      27 |   private static createRequestConfig(options: RequestHeader): RequestConfig {

      at new CoreApiService (src/app/core-api/core-api.service.ts:24:38)
      at Injector.instantiateClass (../../node_modules/@nestjs/core/injector/injector.js:286:19)
      at callback (../../node_modules/@nestjs/core/injector/injector.js:42:41)
      at Injector.resolveConstructorParams (../../node_modules/@nestjs/core/injector/injector.js:114:24)
      at Injector.loadInstance (../../node_modules/@nestjs/core/injector/injector.js:46:9)
      at Injector.loadProvider (../../node_modules/@nestjs/core/injector/injector.js:68:9)
          at async Promise.all (index 5)
      at InstanceLoader.createInstancesOfProviders (../../node_modules/@nestjs/core/injector/instance-loader.js:43:9)
      at ../../node_modules/@nestjs/core/injector/instance-loader.js:28:13
          at async Promise.all (index 1)
      at InstanceLoader.createInstances (../../node_modules/@nestjs/core/injector/instance-loader.js:27:9)
      at InstanceLoader.createInstancesOfDependencies (../../node_modules/@nestjs/core/injector/instance-loader.js:17:9)
      at TestingModuleBuilder.compile (../../node_modules/@nestjs/testing/testing-module.builder.js:43:9)

  ● CoreApiService › should be defined

    expect(received).toBeDefined()

    Received: undefined

      44 |   it('should be defined', () => {
      45 |     console.log('SHOULD BE DEFINED')
    > 46 |     expect(service).toBeDefined();
         |                     ^
      47 |   });
      48 | });
      49 |

      at Object.<anonymous> (src/app/core-api/core-api.service.spec.ts:46:21)

current test file looks like:当前的测试文件如下所示:

import { Test, TestingModule } from '@nestjs/testing';
import { CoreApiService } from './core-api.service';
import { ConfigService } from '@nestjs/config';
import { HttpService, INestApplication } from '@nestjs/common';

class ConfigServiceMock {
  get(key: string): string {
    switch (key) {
      case 'API_SERVICE_ENDPOINT':
        return '';
    }
  }
}

class HttpServiceMock {
  get(): any {

  }
}

describe('CoreApiService', () => {
  let module: TestingModule;
  let service: CoreApiService;
  let app: INestApplication;

  beforeEach(async () => {
    console.log('beforeEach')
    module = await Test.createTestingModule({
      imports: [],
      providers: [
        { provide: ConfigService, useClass: ConfigServiceMock },
        { provide: HttpService, useClass: HttpServiceMock },
        CoreApiService,
      ],
    })
      .compile();
    console.log('COMPILED');
    app = module.createNestApplication();
    await app.init();
    service = module.get<CoreApiService>(CoreApiService);
  });

  it('should be defined', () => {
    console.log('SHOULD BE DEFINED')
    expect(service).toBeDefined();
  });
});

I've also played with the order of the provider section, but I guess this is not relevant...我也玩过提供者部分的顺序,但我想这不相关......

Two things that you may want to try out:您可能想尝试两件事:

  1. Init your Nest application.初始化您的 Nest 应用程序。 Inside the beforeEach , after calling compile() in your module, add these lines:beforeEach中,在模块中调用compile()之后,添加以下行:
app = module.createNestApplication();
await app.init();
  1. Don't import the ConfigModule on your test.不要在您的测试中导入ConfigModule This will initialise the actual config service, which you don't need as you're mocking it.这将初始化实际的配置服务,您不需要它,因为您是 mocking 它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM