我有一个简单的类,我正在尝试使用 NestJS 和端到端测试来确保验证正常工作,但我无法使验证正常工作。如果我使用 Postman 或普通客户端发送数据,应用程序会以正确的错误响应。
API.dto.ts
import { IsNumber, IsPositive, IsString } from 'class-validator';
export class ApiDTO {
@IsString() public readonly FileName:string;
@IsNumber() @IsPositive() public readonly StatusCode:number;
@IsNumber() @IsPositive() public readonly TimeOut:number;
}
端到端测试文件
import { Test, TestingModule } from '@nestjs/testing';
import * as request from 'supertest';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import { AppModule } from '@APP/app.module';
import { ApiDTO } from './../../src/api/api.dto';
describe('ApiController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
app.useGlobalPipes(new ValidationPipe());
await app.init();
});
it('/api/test/ (POST) test to see data validation works', async done => {
const RequestBody:ApiDTO = {
FileName : 'README.md',
StatusCode: 111,
TimeOut: -25
};
const Expected:string = `${RequestBody.FileName} = ${RequestBody.StatusCode.toString()} after ${RequestBody.TimeOut.toString()}`;
const ResponseData = await request(app.getHttpServer())
.post('/api/test')
.send(RequestBody)
.set('Accept', 'application/json');
// All of these will fail as the code returns a 200 OK, as it does not do the validation (TimeOut -25 should fail IsPositive())
expect(ResponseData.status).toBe(400);
expect(ResponseData.headers['content-type']).toContain('application/json');
// This line caused the problem as body is an object
//expect(ResponseData.body.length).toBeGreaterThan(2);
expect(ResponseData.body.statusCode).toBe(400);
expect(ResponseData.body.message[0]).toBe('TimeOut must be a positive number');
expect(ResponseData.body.error).toBe('Bad Request');
done();
});
});
在进行此调用时,我成功返回了 200。我的代码应该会失败,因为 TimeOut 是负数,它需要是 IsPositive()
。服务和其他代码都在运行,只是没有验证。我在 beforeEach() 中添加了全局管道,所以不确定还有什么要检查的。
答案 0 :(得分:0)
我在测试中发现了错误。一旦我将 ValidationPipe() 添加到应用程序定义中:
app = moduleFixture.createNestApplication();
app.useGlobalPipes(new ValidationPipe()); // <- This addition
await app.init();
这使验证能够正常运行。测试失败,因为我正在检查响应正文的长度,
it('/api/test/ (POST) test to see data validation works', async done => {
...
expect(ResponseData.body.length).toBeGreaterThan(10);
...
done();
});
ResponseData.body 是一个对象,因此该对象的 .length
无效。消除这种期望解决了我的问题。
it('/api/test/ (POST) test to see data validation works', async done => {
const RequestBody:ApiDTO = {
FileName : 'README.md',
StatusCode: 111,
TimeOut: -25
};
const Expected:string = `${RequestBody.FileName} = ${RequestBody.StatusCode.toString()} after ${RequestBody.TimeOut.toString()}`;
const ResponseData = await request(app.getHttpServer())
.post('/api/test')
.send(RequestBody)
.set('Accept', 'application/json');
expect(ResponseData.status).toBe(400);
expect(ResponseData.headers['content-type']).toContain('application/json');
expect(ResponseData.body.statusCode).toBe(400);
expect(ResponseData.body.message[0]).toBe('TimeOut must be a positive number');
expect(ResponseData.body.error).toBe('Bad Request');
done();
});