超测return差一个body

Supertest return a different body

我有一个 e2e 测试,我在其中测试注册(唯一的电子邮件)

测试是:

    it('Register a default user: /api/v1/auth/email/register (POST)', async () => {

        return request(app.getHttpServer())
          .post('/auth/email/register')
          .send({
            "name": newUserName,
            "username": newUsername,
            "email": TESTER_EMAIL,
            "password": TESTER_PASSWORD
          })
          .expect(201);
      });

第二次,使用相同的值,我希望得到 400 状态码,我得到了。

    it('Register a default user: /api/v1/auth/email/register (POST)', async () => {

        return request(app.getHttpServer())
          .post('/auth/email/register')
          .send({
            "name": newUserName,
            "username": newUsername,
            "email": TESTER_EMAIL,
            "password": TESTER_PASSWORD
          })
          .expect(400)
          .expect(({ body }) => {
            console.log(body);
          });
      });

如果我分析 Body,我可以看到:

     {
          index: 0,
          code: 11000,
          keyPattern: { email: 1 },
          keyValue: { email: 'john.doe@example.com' }
        }

它是正确的,因为我的 mongoDB 上有一个唯一的索引。 但我希望从我的作品中收到相同的响应 API。

{
  "statusCode": 400,
  "message": [
    "username already exist",
    "email already exist"
  ],
  "error": "Bad Request"
}

控制器很简单,我有这样的路线:

      @Post('email/register')
      @HttpCode(HttpStatus.CREATED)
      async register(@Body() authRegisterLoginDto: AuthRegisterLoginDto) {
        return this.authService.register(authRegisterLoginDto);
      }

为我服务:

    async register(authRegisterLoginDto: AuthRegisterLoginDto) {
    
        const hash = crypto.createHash('sha256').update(randomStringGenerator()).digest('hex');
        const user = await this.usersService.create({
          ...authRegisterLoginDto,
          hash,
        });
    
        await this.mailService.userSignUp({
          to: user.email,
          data: {
            hash,
          },
        });
      }

在我的用户服务中(如果我收到错误)是:

    async create(userDto: UserDto): Promise<IUsers> {
        try {
          return await this.userModel.create(userDto);
        } catch (err) {      
          throw new HttpException(err, HttpStatus.BAD_REQUEST);
        }
      }

如何获得与“产品”API 相同的响应?

更新。

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe, VersioningType } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { TransformationInterceptor } from './interceptors/transformInterceptor';
import { TransformError } from './interceptors/transformErrorInterceptor';
import { useContainer } from 'class-validator';
import { ConfigService } from '@nestjs/config';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);
  //added for custom validator
  useContainer(app.select(AppModule), {fallbackOnErrors: true});
  //custom response
  app.useGlobalInterceptors(new TransformationInterceptor)
  app.useGlobalInterceptors(new TransformError)  
  app.setGlobalPrefix(configService.get('app.apiPrefix'), {
    exclude: ['/'],
  });
  app.enableVersioning({
    type: VersioningType.URI,
  });
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
      forbidNonWhitelisted: true,
      transformOptions: {
        enableImplicitConversion: true,
      },
    }),
  );

  const config = new DocumentBuilder()
    .setTitle('API')
    .setDescription('The API description')
    .setVersion('1.0')
    .addBearerAuth(
      {
        type: 'http',
        scheme: 'bearer',
        bearerFormat: 'JWT',
        name: 'JWT',
        description: 'Enter JWT token',
        in: 'header',
      },
      'JWT-auth', // This name here is important for matching up with @ApiBearerAuth() in your controller!
    )
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api/doc', app, document);

  app.enableCors();
  await app.listen(configService.get('app.port'));

}
bootstrap();

开玩笑-e2e.json

{
  "moduleFileExtensions": ["js", "json", "ts"],
  "rootDir": ".",
  "testEnvironment": "node",
  "testRegex": ".e2e-spec.ts$",
  "transform": {
    "^.+\.(t|j)s$": "ts-jest"
  }
}

我看不出您的 E2E 测试是如何引导应用程序的,但请确保包含所有转换管道以及可能涉及更改错误响应的所有其他内容。

要在 e2e 测试中获得相同的效果,请始终包括您在 main.ts 中的设置,swagger 文档或一些不相关的内容除外。

对于你的情况,我会试试这个

let app: INestApplication;

beforeEach(async () => {

  const moduleFixture: TestingModule = await Test.createTestingModule({
    imports: [AppModule],
  }).compile();

  app = moduleFixture.createNestApplication();
  app.useGlobalInterceptors(new TransformationInterceptor);
  app.useGlobalInterceptors(new TransformError);

  await app.init();
});

感谢@n1md7,我导入了 useContainer(app.select(AppModule), { fallbackOnErrors: true });

进入我的端到端测试。我修改它是因为我想使用

  @Validate(UniqueValidator, ['username'], {
    message: 'username already exist',
  })

在我的 Dto 中。 ()