我目前正在使用 NestJs 和节点测试运行器启动一个新项目。 我的测试服务正在运行,但我的 e2e 测试却无法运行。
这是我的控制器:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {
console.log(appService)
}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
这是我的服务:
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
还有我的模块:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
最后是我的 e2e 测试:
import { Test } from '@nestjs/testing';
import test from 'node:test';
import request from 'supertest';
import {INestApplication} from "@nestjs/common";
import * as assert from "assert";
import {AppModule} from "src/demo/app.module";
test.describe('AppController.getHello', () => {
let app: INestApplication;
test.before(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
test.after(async () => {
await app.close();
})
test.it('should return "Hello World!"', async () => {
await request(app.getHttpServer())
.get('/')
.then((response) => assert.strictEqual(response.body, 'Hello World!'))
});
});
这是我使用
glob ./**/*.test.ts -c 'tsx --test'
启动测试时出现的错误:
TypeError: Cannot read properties of undefined (reading 'getHello')
at AppController.getHello (.../app.controller.ts:12:28)
请注意,当我的服务器启动时,一切正常。 有什么想法吗?
tsx
的核心由 esbuild
提供支持,它不支持 Nest 使用的 Typescript 遗留装饰器。这些装饰器很重要,因为它们向 Typescript 提供信息以发出 Nest 需要解决类之间的依赖关系的元数据。如果您确实想避免编写和运行测试之间的构建步骤,并且不介意需要配置文件,则可以将 @swc/register
与 node
命令一起使用,并以这种方式调用您的测试。你需要一个像这样的 .swcrc
文件:
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es2017",
"keepClassNames": true,
"baseUrl": "."
},
"module": {
"type": "commonjs",
"strictMode": true
}
}
并安装
@swc/register
和 @swc/core
,然后您可以使用 node -r @swc/register --test
作为命令而不是 tsx --test
,一切都应该从那里开始工作。如果您有自定义路径别名,您还需要在 .swcrc
文件中设置更多选项
感谢您非常有帮助的回答。 我只需使用未弃用的包
@swc-node/register
代替 @swc/register
并使用命令
node --import @swc-node/register/esm-register --test'
启动,您提供的命令产生了编译错误。