[英]NestJS Testing: decorator is not a function
我的依賴:
"@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()
錯誤如果我從@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';
我嘗試在MyService
聲明之前添加到my.service.ts
:
console.log('InjectDatabase', InjectDatabase)
並收到:
InjectDatabase: undefined
因此,似乎 Jest 無法解析導入 o 打字稿配置有問題。
在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"
for "@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"
: import Stuff from "@infra/sub/folder/module"
返回undefined
當路徑如下: import Stuff from "@infra
工作就像一個魅力。
我在@infra
lib 中修復了桶文件以正確導出內容並修復導入以使用縮短路徑,這有助於解決問題。
我仍然很好奇為什么設置 Jest: "@infra/(.*)": "<rootDir>/libs/infrastructure/src/$1"
under: moduleNameMapper
不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.