微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

NestJS测试:装饰器不是函数

如何解决NestJS测试:装饰器不是函数

我的依赖项:

"@nestjs/common": "7.4.4","@nestjs/core": "7.4.4","typescript": "4.0.2","jest": "26.4.2","jest-junit": "11.1.0","ts-jest": "26.3.0",

我有一个自定义的装饰器:

import { Inject } from "@nestjs/common";

import { DATABASE_SERVICE } from "./database.constants";

export const InjectDatabase = () => Inject(DATABASE_SERVICE);

我在构造函数中将其用于我愿意用测试介绍的服务:

import {
  DatabaseService,InjectDatabase
} from "@infra/modules";
import { Injectable } from "@nestjs/common";

@Injectable()
export class MyService {
  constructor(
    @InjectDatabase() private readonly db: DatabaseService
  ) {}
}

这是我设置测试模块的方式:

import { Test } from "@nestjs/testing";

import { MyService } from "../../../src/shared/services/my.service";
import { SharedModule } from "../../../src/shared/shared.module";

describe(`MyService`,() => {
  let myService: MyService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [SharedModule]
    }).compile();

    myService = moduleRef.get<MyService>(MyService);
  });
  test("tests",() => {
    // console.log("test");
  });
});

SharedModule是带有@Global()装饰器的模块,并且在提供者/导出中包含MyService

当我尝试执行测试时,出现错误

TypeError: modules_1.InjectDatabase is not a function

      51 | 
      52 |   constructor(
    > 53 |     @InjectDatabase() private readonly adb_db: DatabaseService,|      ^
      56 |   ) {}

      at Object.<anonymous> (apps/workers/my/src/shared/services/my.service.ts:53:6)
      at Object.<anonymous> (apps/workers/my/test/shared/services/my.service.unit.test.ts:8:1)

我遵循了上面显示的跟踪和步骤:

  • 导入文件并进行测试: import { MyService } from "../../../src/shared/services/my.service";
  • 在服务构造函数中的@InjectDatabase()处引发错误

如果我从@InjectDatabase切换到@Inject(DATABASE_SERVICE)

@Injectable()
export class MyService {
  constructor(
    @Inject(DATABASE_SERVICE) private readonly db: DatabaseService
  ) {}
}

我收到另一个错误

Error: nest can't resolve dependencies of the CacheService (?). Please make sure that the argument dependency at index [0] is available in the RoottestModule context.

我试图这样设置测试模块:

    const moduleRef = await Test.createTestingModule({
      imports: [DatabaseModule],providers: [
        {
          provide: DATABASE_SERVICE,useClass: DatabaseService
        },MyService
      ]
    }).compile();

但这并没有帮助,同样的问题:

Error: nest can't resolve dependencies of the CacheService (?).

我的tsconfig.json编译器选项:

  "compilerOptions": {
    "target": "es2018","module": "commonjs","outDir": "dist/","esModuleInterop": true,"strict": true,"sourceRoot": "/","sourceMap": true,"experimentalDecorators": true,"emitDecoratorMetadata": true,"strictPropertyInitialization": false,"removeComments": true,"resolveJsonModule": true
  }

我在jest.config.js中有

setupFiles: ["./jest-setup-file.ts"],

文件仅导入了反射库:

import 'reflect-Metadata';

我试图在my.service.ts声明之前添加MyService

console.log('InjectDatabase',InjectDatabase)

并收到:

InjectDatabase: undefined

所以看来Jest无法解析导入,或者打字稿配置有问题。

MyService中导入的装饰器函数为:

import {
  DatabaseService,InjectDatabase
} from "@infra/modules";

我的jest.config.js

module.exports = {
  bail: 0,verbose: true,preset: "ts-jest",testEnvironment: "node",roots: ["<rootDir>/libs","<rootDir>/apps"],testRegex: ".*\\.test\\.ts$",testPathIgnorePatterns: ["/node_modules/","/dist/","/build/"],modulefileExtensions: ["ts","js","json"],moduleNameMapper: {
    "@common": "<rootDir>/libs/common/src","@common/(.*)": "<rootDir>/libs/common/src/$1","@infra": "<rootDir>/libs/infrastructure/src","@infra/(.*)": "<rootDir>/libs/infrastructure/src/$1"
  },transform: {
    "^.+\\.ts?$": "ts-jest"
  },setupFiles: ["./jest-setup-file.ts"],collectCoverage: true,coverageThreshold: {
    global: {
      branches: 80,functions: 80,lines: 80,statements: 80
    }
  },coverageReporters: ["json","lcov","text","clover"],coveragePathIgnorePatterns: ["/node_modules/"]
};

对于moduleNameMapper"@infra/(.*)": "<rootDir>/libs/infrastructure/src/$1"可能无法正确解决"@infra/modules"吗?

在测试之外-一切正常。

如何正确设置jest / typescript / nest,以便我的自定义装饰器正确识别?

解决方法

经过更好的调试,我发现Jest不能以某种方式将子文件夹的路径别名解析为模块,并且不加载导入的内容,而是返回未定义的内容。 jest.config.js中的设置:

    "@infra": "<rootDir>/libs/infrastructure/src","@infra/(.*)": "<rootDir>/libs/infrastructure/src/$1"

所以上面的第二行不适用于Jest。 具有以下路径的所有进口: import Stuff from "@infra/sub/folder/module" 正在返回undefined 当路径像: import Stuff from "@infra 就像魅力一样。

我修复了@infra库中的桶文件,以正确导出内容,并修复了导入以使用较短的路径,这有助于解决此问题。

我仍然很好奇为什么要开玩笑: "@infra/(.*)": "<rootDir>/libs/infrastructure/src/$1" 下: moduleNameMapper 不起作用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。