使用嵌套对象时,我很难让我的 ValidationPipe 在类验证器中工作。
例如,我有 NestedObject 格式:
{
Data: '123',
Value: 567
}
然后我创建了nested-object.ts 类:
import { IsNumber, IsNumberString, Min, MinLength } from 'class-validator';
export class NestedObject {
@IsNumberString() @MinLength(2) public readonly Data: string;
@IsNumber() @Min(2) public readonly Value: number;
}
然后我可以编写一个 Jest 测试用例来覆盖 ValidationPipe 中的这个嵌套对象,并验证数据。
嵌套对象.spec.ts
import { ArgumentMetadata, HttpStatus, ValidationPipe } from '@nestjs/common';
import { NestedObject } from './nested-object';
describe('NestedObject', () => {
it('should be defined', () => {
expect(new NestedObject()).toBeDefined();
});
it('should validate the NestedObject definition for JSON payload { Data: null, Value: 0 }', async () => {
const target: ValidationPipe = new ValidationPipe({
transform: true,
whitelist: true,
enableDebugMessages: true,
errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
});
const metadata: ArgumentMetadata = {
type: 'body',
metatype: NestedObject,
data: '',
};
const Expected: string[] = [
'Data must be longer than or equal to 2 characters',
'Data must be a number string',
'Value must not be less than 2',
];
await target.transform({ Data: null, Value: 0 }, metadata).catch((err) => {
expect(err.getResponse().statusCode).toBe(HttpStatus.UNPROCESSABLE_ENTITY);
expect(err.getResponse().message).toEqual(Expected);
});
});
});
上述测试通过。我已经创建了基本对象,这很好用。我的问题是当我现在尝试在另一个类中验证这个对象时。新的类验证有效,但嵌套对象无效。
父对象.ts
import { Type } from 'class-transformer';
import { IsString, MinLength, ValidateNested } from 'class-validator';
import { NestedObject } from './nested-object';
export class ParentObject {
@IsString() @MinLength(1) public readonly FileName: string;
@ValidateNested()
@Type(() => NestedObject)
public Child: NestedObject;
}
我现在期望我的 ParentObject 将是:
{
FileName: 'abc.txt',
Child: {
Data: '123',
Value: 567
}
}
然后我为 ParentObject 编写测试用例。
父对象.spec.ts
import { ArgumentMetadata, HttpStatus, ValidationPipe } from '@nestjs/common';
import { NestedObject } from './nested-object';
import { ParentObject } from './parent-object';
describe('ParentObject', () => {
it('should be defined', () => {
expect(new ParentObject()).toBeDefined();
});
it('should validate the ParentObject & NestedObject for JSON payload { FileName: null, Child: { Data: null, Value: 0 } }', async () => {
const target: ValidationPipe = new ValidationPipe({
transform: true,
whitelist: true,
enableDebugMessages: true,
errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
});
const metadata: ArgumentMetadata = {
type: 'body',
metatype: ParentObject,
data: '',
};
const Expected: string[] = [
'FileName must be longer than or equal to 1 characters',
'FileName must be a string',
'Child.Data must be longer than or equal to 2 characters',
'Child.Data must be a number string',
'Child.Value must not be less than 2',
];
await target.transform({ FileName: null, Child: { Data: null, Value: 0 } }, metadata).catch((err) => {
expect(err.getResponse().statusCode).toBe(HttpStatus.UNPROCESSABLE_ENTITY);
expect(err.getResponse().message).toEqual(Expected);
});
});
});
测试失败。该测试仅返回 FileName 验证,而不是应该来自 NestedObject 的 3 个 Child 验证。
- Expected - 3
+ Received + 2
Array [
- "Child.Data must be longer than or equal to 2 characters",
- "Child.Data must be a number string",
- "Child.Value must not be less than 2",
+ "FileName must be longer than or equal to 1 characters",
+ "FileName must be a string",
]
验证运行并检测到 FileName 问题,但未发现 NestedObject 错误。使用 NestedObject 时我是否错误地构建了对象?我是否在测试中遗漏了一些东西来检查子节点?