[Nest.js] e2e test에서 global validation pipe사용하기

Donghun Seol·2023년 5월 6일
0

0. 배경

e2e 테스트 학습하면서 작성중이다.
테스트 작성하면서 여러 문제를 마주했고, 해결한 문제 한가지를 포스팅해보고자 한다.
(특히 Nest.js의 httpService를 사용할 때 Observable을 다루는 문제는 아직 해결하지 못하고 있다. http요청 결과로 생성되는 Observable 스트림에서 성공, 실패를 필터하고 해당 데이터를 적절하게 가공한 다음 테스트에 활용하는 부분이 잘 되지 않음... )

1. 문제

e2e 테스트를 위해 app객체를 셋업했는데, validation pipe가 정상적으로 적용되지 않는 문제를 발견했다.

바람직한 api의 응답은 다음과 같이 validation pipe가 적용된 형태여야 하는데
'{"statusCode":400,"message":["address must be an Ethereum address"],"error":"Bad Request"}'

실제로는 이런 응답이 왔다. 아래와 같은 응답은 서버단에서 잘못된 요청을 거르지 못하고 DB를 조회한 후 반환된 에러메시지를 전달하는 응답이다.
'{"statusCode":404,"message":"no such user","error":"Not Found"}'

app 객체 셋업에 사용한 코드는 다음과 같다.

//app.e2e-spec.ts
beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    })
      .overrideProvider(PriceFeedService)
      .useValue({})
      .compile();
    app = moduleFixture.createNestApplication();
    httpService = moduleFixture.get<HttpService>(HttpService);
    await app.init();
  });

2. 해결

해결책은 당연하게도 e2e테스트 파일의 app객체 셋업과정에 명시해주는 것이었다.
e2e테스트에서 셋업되는 app객체는 main.ts의 컨텍스트를 반영하지 않으므로 수동으로 명시해줘야 하는 것이다.

main.ts 파일의 bootstrap() 함수는 다음과 같이 정의되어 있다.

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors({
    origin: ['http://localhost:3001'],
    methods: ['GET', 'POST'],
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true,
  });
  // somewhere in your initialization file
  app.use(cookieParser());
  app.useGlobalPipes(new ValidationPipe({ transform: true }));
  await app.listen(3000);
}

main.ts 파일에서 app객체에 적용된 컨텍스트는 다음과 같이 테스트파일에서도 명시해주자.

//app.e2e-spec.ts
beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    })
      .overrideProvider(PriceFeedService)
      .useValue({})
      .compile();
    app = moduleFixture.createNestApplication();
    httpService = moduleFixture.get<HttpService>(HttpService);
  	// Add below to use Global Pipe in testing module
    app.useGlobalPipes(new ValidationPipe({ transform: true }));
    await app.init();
  });
profile
I'm going from failure to failure without losing enthusiasm

5개의 댓글

comment-user-thumbnail
2023년 5월 12일

sample mocking comment for api test

답글 달기
comment-user-thumbnail
2023년 5월 13일

sample mocking comment for api test

답글 달기
comment-user-thumbnail
2023년 5월 13일

sample mocking comment for api test

답글 달기
comment-user-thumbnail
2023년 5월 24일

3. 결론

e2e 테스트 작성 시 app객체 셋업 부분에서 전역으로 적용되는 Validation Pipe를 명시하는 것을 기억하자.
기본적으로 Nest.js는 main.ts의 bootstrap함수를 통해 컨텍스트를 적용하는데, 이 파일을 e2e테스트에서 가져오는 것은 피하는 것

답글 달기
comment-user-thumbnail
2023년 5월 24일

3. 결론

Nest.js e2e테스트에서 Global validation pipe을 사용하기 위해 해당 Pipe이 적용된 컨텍스트가 반드시 테스트 셋업 과정에 명시되어야 한다는 것을 학습하였다.

Summary:
This article discusses the issue of not properly applying global validation pipes when setting up an app object for Nest.js e2e tests. The solution to this problem is to explicitly indicate the context with the global pipe applied in the test setup process, as Main.ts bootstrap () function defines what the app object would have when setting up. This article then provides a conclusion reiterating the need to explicitly specify the context with the global pipe applied when setting up the app object for Nest.js e2e tests.

Point out any technically wrong statements:
No technically wrong statements were found.

Suggest way to improve article:
The article could be improved by including more detailed information on the Main.ts bootstrap() function, further examples of the issue, and an example of the explicit context code in action.

Suggest good materials to study on the article's topic with reference:
To further study on the problem of not properly applying global validation pipes when setting up an app object for Nest.js e2e tests, readers could check out the documentation from Nest.js (https://docs.nestjs.com/techniques/validation) as well as the blog post "Testing NestJS with Jest and SuperTest" (https://dev.to/staxmanade/testing-nestjs-with-jest-and-supertest-3gf1).

답글 달기