如何解决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 举报,一经查实,本站将立刻删除。