본문 바로가기

Backend/NestJS

[NestJS Overview] NestJS jest로 테스트하기(1) (unit testing)

728x90
jest를 이용해 NestJS의 API를 테스트해봤다.
이에 대한 공부 기록이다.

jest

jest는 JS를 테스팅하는 npm package이다.

NestJS는 테스팅에 대한 세팅을 끝내고 우리에게 제공한다.

 

jest를 통해 하는 테스팅은 크게 두 개로 나뉜다.

  1. unit testing : 하나의 유닛만 테스팅할 수 있다. 모듈 간의 관계는 테스트할 수 없다.
  2. e2e testing : 테스트하고자 하는 모듈 관련 모든 부분을 테스트한다.

이번 기록은 unit testing에 대한 기록이다.

e2e testing은 추후 기록에서 다룰 예정이다.

 

지금까지의 NestJS 기록에서 언급이 없었던 spec.ts파일이 unit testing을 위한 파일이다.

 

package.json의 test 관련 명령어들을 보자.

    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"

scripts 속성에 위와 같은 값들을 볼 수 있다.

여기서 이번에 우리가 쓸 것은

test:watch와 test:cov이다.

  1. test:watch : 이 명령어는 spec.ts 파일을 저장할 때마다 자동으로 test 해주는 명령어이다.
  2. test:cov : 이 명령어는 테스트 상황을 알려준다. 테스트가 안 된 함수 등의 퍼센트와 몇 줄에 있는지 표시해준다.

사진과 같이 todos.service.ts 파일의 함수가 testing되지 않은 것을 확인할 수 있다.

 

service 파일의 함수들은 모두 이전 기록에 있다.

 

[NestJS Overview] Service.ts(서비스 파일, 반환 클래스, 예외처리)

NestJS 서비스 파일에 대한 기록이다. 개요 이번 기록에서는 비즈니스 로직의 역할을 맡는 서비스 파일에 대한 기록이다. 비즈니스 로직을 어떻게 작성할지, 반환하는 객체에 대한 클래스 생성,

choi-records.tistory.com

이제 spec.ts 파일에서 테스팅을 해보자.

spec.ts

//todos.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { TodosService } from './todos.service';

describe('TodosService', () => {
  let service: TodosService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [TodosService],
    }).compile();

    service = module.get<TodosService>(TodosService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });
});
  • describe : 테스트의 시작을 의미하는 메서드이다. describe 메서드 안에 다른 describe 메서드가 들어갈 수 있다.
  • beforeEach : 테스트 시작 전 실행할 코드를 작성할 수 있는 메서드이다. 위에서는 TodoService를 통해 메서드를 가진 service를 선언했다. 이제 service 파일의 메서드를 사용할 수 있다.
  • it() : individual test 각각의 함수를 it 메서드를 이용해 테스트하면 된다.
  • expect() : 테스트에서 비교할 값을 인자로 받는다. 즉, 함수의 반환값을 넣고, 해당 메서드가 반환하는 jestMatchers와의 비교를 하면 된다.

Test

getAll, getOne, deleteOne, create, update 메서드를 테스트하면 된다.

getOne 메서드 하나만 해보자.

  getOne(id: number) {
    const toDo = this.todos.find((toDo) => toDo.id === +id);
    if (!toDo) {
      throw new NotFoundException(`wrong id : ${id}`);
    }
    return toDo;
  }

getOne 메서드의 모습이다.

이 메서드는 toDo를 반환할 수도 있고, 에러를 반환할 수도 있다.

두 경우에 대해 모두 test 해줘야 한다.

 

getOne을 테스트하려면 create가 선행되어야 한다.

다른 API를 테스트할 때도 create가 필요하므로, create를 beforeEach에 추가해보자.

 

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [TodosService],
    }).compile();

    service = module.get<TodosService>(TodosService);
    service.create({
      action: 'study',
    });
  });

create를 이용해서 todos에 todo 하나를 추가해줬다.

 

이제 getOne() 메서드를 test 해보자.

  it('should get a todo', () => {
    const todo = service.getOne(1);
    expect(todo.id).toEqual(1);
  });

먼저 정상적으로 추가됐을 때의 상황을 test 해봤다.

it 메서드의 첫 번째 인자로 전달된 문자열은 정상적으로 test가 완료됐을 때 반환되는 문자열이다.

위의 사진에서 볼 수 있듯 정상적으로 test가 완료되었음을 알 수 있다.

 

이번엔 잘못된 ID로 요청했을 때의 상황을 test 해보자.

it('should return 404 error', () => {
    try {
      service.getOne(999);
    } catch (e) {
      expect(e.message).toEqual('wrong id : 999');
    }
  });

잘못된 id로 getOne 요청을 하고,

catch에서 에러 처리될 때 에러가 정상적으로 전달되는지, 에러 메세지가 설정값과 같은지 test 했다.

정상적으로 test된 것을 알 수 있다.

 

다시 test:cov로 test 현황을 보자.

맨 마지막 test가 안 된 메서드의 줄 번호 중

getOne 메서드의 줄 번호가 없어진 것을 볼 수 있다.

 

정상적으로 getOne 메서드에 대한 test가 완료된 것이다.


출처

 

NestJS로 API 만들기 – 노마드 코더 Nomad Coders

Enterprise Server Side Applications

nomadcoders.co

마치며

잘못된 정보에 대한 피드백은 환영입니다.

감사합니다.

728x90