getOne(id: number): Movie {
console.log(id);
...
}
Insomnia에서 확인
POST로 데이터를 담고 getOne()으로 테스트합니다.
💡 근데 테스트할 때는 왜 안 나올까요?
id의 type을 확인해봅니다.
getOne(id: number): Movie {
console.log(typeof id);
... }
반응형
npm run test:e2e로 확인해봅니다.
→ 테스트에서는 string으로 나옵니다.
→ movie.id 는 number이고, id는 string이기 때문에 찾을 수 없다고 뜨는 것
💡 왜 실서버에서의 id는 number이고, 테스트 서버에서는 string으로 나올까요?
main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({
whitelist:true, // 아무 decorator 도 없는 어떤 property의 object를 거름
forbidNonWhitelisted: true, // 잘못된 property의 리퀘스트 자체를 막아버림
transform: true, // 실제 원하는 타입으로 변경해줌
}));
await app.listen(3000);
}
transform이라는 것을 넣었습니다.
그래서 getOne()을 호출할 때 id 가 내가 원하는 number 타입으로 변경됩니다.
getOne(id: number): Movie
하지만 문제는 url 은 string입니다.
어떤 이유인지 e2e 테스트에서 transform 이 작동하지 않습니다. → 왜냐하면 e2e 테스트할 때 새로운 앱을 생성을 하는데 어떤 pipe 에도 올리지 않음..
💡 테스트에도 실제 애플리케이션 환경을 그대로 적용시켜줘야 합니다!!
app.e2e-spec.ts
...
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
app.useGlobalPipes(new ValidationPipe({
whitelist:true, // 아무 decorator 도 없는 어떤 property의 object를 거름
forbidNonWhitelisted: true, // 잘못된 property의 리퀘스트 자체를 막아버림
transform: true, // 실제 원하는 타입으로 변경해줌
}));
await app.init();
});
...
💡 새로 파일들을 생성하면 파일명 뒤에 .spec.ts 라고 붙은 파일들이 같이 생성되는데 그 파일들이 테스트를 포함한 파일입니다.
Nestjs에서는 jest 가. spec.ts 파일들을 찾아볼 수 있도록 설정되어있습니다.
npm run test:cov
모든 .spec.ts 파일을 찾아서 몇 줄이 테스팅됐는지 알려줍니다.
npm run test:watch
모든 테스트 파일들을 찾아서 거기서 무슨 일이 일어나는지 관찰합니다.
Unit Testing
서비스에서 분리된 유닛을 테스트한다.
모든 function 을 따로 테스트 ex) movie.service.ts > getAll() 함수 하나만 테스트하고 싶을 때 사용
e2e Testing (end-to-end)
모든 시스템을 테스팅한다. ex) 이 페이지로 가면 특정 페이지가 나와야 하는 경우 사용
Jest
자바스크립트 테스팅 프레임워크
Unit Test
💡 afterAll() 안에는 데이터베이스를 모두 지우는 function을 넣을 수 있음 beforeEach, afterEach, beforeAll, afterAll 등 많은 훅이 있습니다.
간단한 프로젝트를 통해 unit test를 진행해보도록 하겠습니다.
movies.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { MoviesService } from './movies.service';
describe('MoviesService', () => { // 테스트를 묘사..?
let service: MoviesService;
beforeEach(async () => { // 테스트하기전에 실행
const module: TestingModule = await Test.createTestingModule({
providers: [MoviesService],
}).compile();
service = module.get<MoviesService>(MoviesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
맨 하단에 이런 함수를 넣어서 실행해봅니다.
...
it('should be 4', () => {
expect(2+2).toEqual(4);
})
...
npm run test:watch
Unit Testing
getAll()
getAll() 메소드를 호출한 후 result 인스턴스가 배열인지 테스트
describe('getAll', () => {
it('should return an array', () => {
const result = service.getAll();
expect(result).toBeInstanceOf(Array);
});
});
npm run test:watch
→ getAll : shold return an array
getOne()
getOne() 메소드가 잘 호출되는지 테스트
999 id 값을 가진 movie 가 없을 때 에러 메시지를 던지는지 확인
describe('getOne', () => {
// getOne() 을 테스트 할 때 Movie 가 create 되어 있지 않다면 문제가 생길 수 있음
it('should return a movie', () => {
service.create({
title: 'Test',
genres: ['test'],
year: 2020,
});
const movie = service.getOne(1);
expect(movie).toBeDefined();
expect(movie.id).toEqual(1); // movie id 값이 1이 맞는지 확인
});
it('should throw 404 error', () => {
try{
service.getOne(999);
}catch(e){
expect(e).toBeInstanceOf(NotFoundException);
expect(e.message).toEqual('Movie with ID 999 not found.');
}
})
});