2

我希望你能帮助我。我正在使用带有最新 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",
    ...

我无法使用带有 Jest 的 NestJS 运行单元测试我想测试以下服务:

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

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

我收到以下错误:

TypeError: Cannot read property 'get' of undefined

所以似乎 ConfigService(以及 httpService)总是未定义的。

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

它将始终是上述相同的错误。

测试文件:

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();
  });
});


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

先感谢您!

编辑 03/01

似乎模块本身的编译步骤失败了......所以对于当前的测试文件,日志“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)

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

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();
  });
});

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

4

1 回答 1

1

您可能想尝试两件事:

  1. 初始化您的 Nest 应用程序。里面beforeEach,在你的模块中调用后compile(),添加这些行:
app = module.createNestApplication();
await app.init();
  1. 不要ConfigModule在您的测试中导入。这将初始化实际的配置服务,你在模拟它时不需要它。
于 2021-03-01T03:33:12.473 回答