TLNR:我正在尝试在控制器规范中而不是在e2e规范中测试DTO验证,这正是为此而设计的。麦道尼尔的回答为我指明了正确的方向。
我开发了一个NestJS入口点,如下所示:
@Post()
async doStuff(@Body() dto: MyDto): Promise<string> {
// some code...
}
我使用
class-validator
以便当我的API收到请求时,将有效负载解析并转换为MyDto对象,并执行作为MyDto类中的批注呈现的验证。请注意,MyDto具有MySubDto类的嵌套对象数组。使用@ValidateNested和@Type批注,也可以正确验证嵌套对象。这很好。
现在,我想为执行的验证编写测试。在我的.spec文件中,我写:
import { validate } from 'class-validator';
// ...
it('should FAIL on invalid DTO', async () => {
const dto = {
//...
};
const errors = await validate( dto );
expect(errors.length).not.toBe(0);
}
这将失败,因为已验证的dto对象不是MyDto。我可以这样重写测试:
it('should FAIL on invalid DTO', async () => {
const dto = new MyDto()
dto.attribute1 = 1;
dto.subDto = { 'name':'Vincent' };
const errors = await validate( dto );
expect(errors.length).not.toBe(0);
}
现在可以在MyDto对象上正确进行验证,而不是在嵌套的subDto对象上进行验证,这意味着我将不得不使用根据类实例化Dto的所有aaaa对象,这将大大降低效率。另外,实例化类意味着如果我自愿省略一些必需的属性或指示错误的值,TypeScript将引发错误。
所以问题是:
如何在测试中使用NestJs内置的请求主体解析器,以便可以编写想要用于dto的任何JSON,将其解析为MyDto对象并使用
class-validator
validate函数进行验证?也欢迎任何其他替代性更好的做法来测试验证!
最佳答案
为了使用验证管道测试输入验证,我认为最好的方法是在e2e测试中而不是在单元测试中,只需确保记住注册管道即可(如果通常使用app.useGlobalPipes()
使用依赖注入)