mercredi 13 novembre 2019

How to manually test input validation with NestJS and class-validator

I develop a NestJS entrypoint, looking like that:

@Post()
async doStuff(@Body() dto: MyDto): Promise<string> {
  // some code...
}

I use class-validator so that when my API receives a request, the payload is parsed and turned into a MyDto object, and validations present as annotations in MyDto class are performed. Note that MyDto has an array of nested object of class MySubDto. With the @ValidateNested and @Type annotations, the nested objects are also validated correctly.

This works great.

Now I want to write tests for the performed validations. In my .spec file, I write:

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);
}

This fails because the validated dto object is not a MyDto. I can rewrite the test as such:

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);
}

Validations are now properly made on the MyDto object, but not on my nested subDto object, which means I will have to instantiate aaaall objects of my Dto with according classes, which would be much inefficient. Also, instantiating classes means that TypeScript will raise errors if I voluntarily omits some required properties or indicate incorrect values.

So the question is:

How can I use NestJs built-in request body parser in my tests, so that I can write any JSON I want for dto, parse it as a MyDto object and validate it with class-validator validate function?

Any alternate better-practice ways to tests validations are welcome too!

Aucun commentaire:

Enregistrer un commentaire