NestJS로 API 만들기
https://nomadcoders.co/nestjs-fundamentals
노마드코더 강의를 참고하고 있습니다.
spec.ts
Nest.js에서 spec.ts 파일은 유닛 테스트를 작성하는 데 사용하는 파일이다.
특정 모듈, 서비스, 컨트롤러 등의 단위에 대해 테스트를 정의하는 데 사용한다.
일반적으로 Nest.js에서 유닛 테스트를 하기 위해 Jest 프레임워크를 사용한다.
package.json 파일을 보면 이미 jest 설정이 되어있는 것을 확인할 수 있다.
Jest
- describe 함수
describe 함수는 테스트 파일이나 테스트 블록을 정의할 때 사용한다.
describe('Math operations', () => {
// 덧셈에 대한 테스트 그룹
describe('Addition', () => {
it('should correctly add two numbers', () => {
const result = 1 + 2;
expect(result).toBe(3);
});
});
// 뺄셈에 대한 테스트 그룹
describe('Subtraction', () => {
it('should correctly subtract two numbers', () => {
const result = 5 - 2;
expect(result).toBe(3);
});
});
});
- it 함수
it 함수는 테스트 케이스를 정의할 때 사용한다.
it('테스트 설명', () => {
// 테스트 로직
});
- expect 함수
expect 함수는 예상한 결과와 실제 결과를 비교하고, 테스트가 성공적으로 통과했는지 여부를 판단한다.
밑에 예시에서 result가 배열의 인스턴스인지 검사한다.
it('should return an array', () => {
const result = someFunction();
expect(result).toBeInstanceOf(Array);
});
1. service.spec.ts
getAll 메서드 테스트
- getAll 메서드로 가지고 온 값이 Array 인스턴스인지 확인한다.
describe('MoviesService', () => {
describe('getAll', () => {
it('should return an array', () => {
const result = service.getAll();
expect(result).toBeInstanceOf(Array);
});
});
});
getOne 메서드 테스트
- service.create로 영화 데이터를 만든다.
- getOne 메서드로 id가 1인 영화 데이터를 가지고 와 id가 1이 맞는지 비교한다.
- id가 1이 아니라면(getOne(999)) 404 에러를 발생시킨다.
describe('MoviesService', () => {
describe('getOne', () => {
it('should return a movie', () => {
service.create({
title: 'Test Movie',
year: 2024,
genres: ['Test'],
});
const movie = service.getOne(1);
expect(movie).toBeDefined();
expect(movie.id).toEqual(1);
});
it('should throw 404 error', () => {
try {
service.getOne(999);
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
}
});
});
});
deleteOne 메서드 테스트
- service.create로 영화 데이터를 만든다.
- getAll 메서드로 영화의 길이를 변수에 저장한다.
- deleteOne 메서드로 id가 1인 영화를 삭제한다.
- 그 후 다시 getAll 메서드로 영화의 길이를 변수에 저장해 영화를 삭제하기 전과 후의 값을 비교한다.
- 없는 id의 영화(deleteOne(999))를 삭제하면 404 에러를 발생시킨다.
describe('MoviesService', () => {
describe('deleteOne', () => {
it('deletes a movie', () => {
service.create({
title: 'Test Movie',
year: 2024,
genres: ['Test'],
});
const beforeDelete = service.getAll().length;
service.deleteOne(1);
const afterDelete = service.getAll().length;
expect(afterDelete).toBeLessThan(beforeDelete);
});
it('should return a 404', () => {
try {
service.deleteOne(999);
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
}
});
});
});
create 메서드 테스트
- getAll 메서드로 영화의 길이를 변수에 저장한다.
- create 메서드로 새로운 영화를 생성한다.
- 그 후 다시 getAll 메서드로 영화의 길이를 변수에 저장해 영화를 생성하기 전과 후의 값을 비교한다.
describe('MoviesService', () => {
describe('create', () => {
it('should create a movie', () => {
const beforeCreate = service.getAll().length;
service.create({
title: 'Test Movie',
year: 2024,
genres: ['Test'],
});
const afterCreate = service.getAll().length;
expect(afterCreate).toBeGreaterThan(beforeCreate);
});
});
});
update 메서드 테스트
- service.create로 영화 데이터를 만든다.
- update 메서드로 id가 1인 영화의 title을 수정한다.
- getOne 메서드로 해당 영화를 가져와 영화의 title이 'Updated Test'가 맞는지 비교한다.
- 없는 id의 영화(update())를 수정하면 404 에러를 발생시킨다.
describe('MoviesService', () => {
describe('update', () => {
it('should throw a NotFoundException', () => {
service.create({
title: 'Test Movie',
year: 2024,
genres: ['Test'],
});
service.update(1, { title: 'Updated Test' });
const movie = service.getOne(1);
expect(movie.title).toEqual('Updated Test');
try {
service.update(999, {});
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
}
});
});
});
2. 터미널에서 확인하기
터미널에서 아래 명령어를 실행한다.
모든 spec 파일에 대해 테스트가 진행된다.
:watch 옵션을 사용하면 저장할 때마다 자동으로 테스트를 시작한다.
npm run test
또는
npm run test:watch
3. 전체 코드
- src/movies/movies.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { MoviesService } from './movies.service';
import { NotFoundException } from '@nestjs/common';
describe('MoviesService', () => {
let service: MoviesService;
let testMovie;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MoviesService],
}).compile();
service = module.get<MoviesService>(MoviesService);
// 테스트에 사용될 영화 객체 생성, id는 자동으로 생성됨
testMovie = {
title: 'Test Movie',
year: 2024,
genres: ['Test'],
};
});
describe('getAll', () => {
it('should return an array', () => {
expect(service.getAll()).toBeInstanceOf(Array);
});
});
describe('getOne', () => {
it('should return a movie', () => {
service.create(testMovie);
const movie = service.getOne(1);
expect(movie).toBeDefined();
expect(movie.id).toEqual(1);
});
it('should throw 404 error', () => {
try {
service.getOne(999);
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
}
});
});
describe('deleteOne', () => {
it('deletes a movie', () => {
service.create(testMovie);
const beforeDelete = service.getAll().length;
service.deleteOne(1);
const afterDelete = service.getAll().length;
expect(beforeDelete).toBeLessThan(afterDelete);
});
it('should return a 404', () => {
try {
service.deleteOne(999);
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
}
});
});
describe('create', () => {
it('should create a movie', () => {
const beforeCreate = service.getAll().length;
service.create(testMovie);
const afterCreate = service.getAll().length;
expect(afterCreate).toBeGreaterThan(beforeCreate);
});
});
describe('update', () => {
it('should throw a NotFoundException', () => {
service.create(testMovie);
service.update(1, { title: 'Updated Test' });
const movie = service.getOne(1);
expect(movie.title).toEqual('Updated Test');
try {
service.update(999, {});
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
}
});
});
});
'NestJs > Nest 기초' 카테고리의 다른 글
[Nest] #4 E2E TESTING - Jest 앤드 투 앤드 테스트 (0) | 2024.01.10 |
---|---|
[Nest] #2.2 REST API - DTO (0) | 2024.01.05 |
[Nest] #2.1 REST API - 모듈, 컨트롤러, 서비스 (0) | 2024.01.04 |
[Nest] #1 ARCHITECTURE OF NESTJS - 기본 개념 (1) | 2024.01.03 |