nest js 세팅
Nest CLI를 설치한다.
npm i -g @nestjs/cli
새로운 nest 프로젝트를 생성한다.
nest new [프로젝트 이름]
사용할 패키지 매니저를 선택한다. (npm 선택)
npm run start 명령어로 서버를 실행할 수 있다.
npm run start
Dependency Injection (의존성 주입)
DI란 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴이다.
예를 들어 A 객체에서 B 객체를 사용한다고 하면 A 객체에서 직접 B 객체를 생성하지 않고 외부에서 B 객체를 생성해서 넣어주는 것이 DI라고 할 수 있다.
nest js에서는 B 객체처럼 다른 객체에 주입할 객체들을 Provider라고 한다.
nest 기본 프로젝트를 보면 DI를 적용하는 방식을 알 수 있다.
nest new 명령어로 프로젝트를 생성하면 app.controller.ts에서 AppService 객체를 주입받아 사용하고 있다.
Provider에 @Injectable 데코레이션을 달아준다.
<app.service.ts>
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
이 객체를 주입받을 app.controller.ts에서 생성자 방식으로 AppService 객체를 주입받는다.
<app.controller.ts>
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
모듈에 provider를 등록하여 Nest Ioc 컨테이너가 provider를 관리할 수 있도록 한다.
<app.module.ts>
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class AppModule {}
DI가 이루어지는 과정은 다음과 같다.
- Nest IOC 컨테이너가 AppController 인스턴스를 생성할 때 종속성을 찾는다.
- AppServicve 종속성을 찾으면 AppService 클래스를 반환하는 AppService 토큰을 찾는다.
- AppService 인스턴스를 생성한다.
Controller와 Service
nestjs에서는 기본적으로 Controller에게 Service 객체를 주입하는 방식을 사용한다.
controller는 특정 URL 엔드포인트에 대해 처리를 하고 응답을 해주는 역할이다.
service는 비즈니스 로직이 실행되는 곳이며 실질적으로 원하는 동작을 수행하는 곳이다.
역할을 분리하여 controller는 요청, 응답을 주로 수행하며 service는 핵심 로직을 수행한다.
Module, Controller, Serivce 구조
nestjs에서 모듈은 특정 기준으로 관련된 기능들을 모아둔 집합이라고 볼 수 있다.
예를 들어 user에 관련된 기능들은 user 모듈에 넣고 chat에 관련된 기능들은 chat 모듈에 넣을 수 있다.
아래 명령어를 입력하면 모듈을 만들어준다.
nest g module [모듈 이름]
채팅 모듈을 만들고 싶다면 nest g module chat 명령어를 입력한다.
자동으로 chat 디렉토리 내부에 chat.module.ts 파일을 만들어준다.
controller와 service도 명령어를 통해 만들 수 있다.
nest g controller [컨트롤러 이름]
nest g service [서비스 이름]
현재 chat 모듈 작성 중이므로 모두 chat을 입력하자.
역시 chat 디렉토리 내부에 controller와 service를 자동으로 만들어줬고 테스트 파일도 함께 만들어줬다.
기존에 텅 비어있던 module에도 controller와 provider가 등록되었다.
import { Module } from '@nestjs/common';
import { ChatController } from './chat.controller';
import { ChatService } from './chat.service';
@Module({
controllers: [ChatController],
providers: [ChatService]
})
export class ChatModule {}
테스트 작성법
jest 단위 테스트 라이브러리를 사용하는 방법은 다음과 같다.
1. test
test의 첫 번째 인자로 테스트 설명을, 두 번째 인자로 테스트 코드가 담긴 함수를 넣어준다.
test('기본 테스트', ()=>{
// 테스트 코드
})
2. describe
비슷한 유형의 test를 묶을 수 있다.
test의 첫 번째 인자로 테스트 설명을, 두 번째 인자로 여러 test가 담긴 함수를 넣어준다.
describe('loginUser', ()=>{
test('첫 번째 테스트', ()=>{})
test('두 번째 테스트', ()=>{})
test('세 번째 테스트', ()=>{})
}
3. expect
expect 안에 테스트 할 값을 넣어주고 matchers를 사용해서 값을 검증할 수 있다.
test('기본 테스트', ()=>{
expect(1+1).toBe(2)
expect(1+1).toEqual(2)
expect(3).toBeLessThan(4)
expect(1).not.toBeNull()
})
nestjs에서는 spec.ts로 파일을 작성하면 ㅔ테스트 코드로 인식한다.
AppService의 getHello 메소드에 대해서 테스트 코드를 작성하면 다음과 같다.
<AppService.spec.ts>
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { Test, TestingModule } from "@nestjs/testing";
describe("AppService", () => {
let appService: AppService;
test("getHello", async ()=>{
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appService = app.get<AppService>(AppService);
expect(appService.getHello()).toBe("Hello World!");
})
})
테스트 코드 작성 후 npm run test 명령어를 사용하면 테스트 결과를 알 수 있다.
npm run test
댓글