일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- typeORM
- 공룡게임
- game
- dfs
- Queue
- AWS
- 자료구조
- Sequelize
- cookie
- nodejs
- 정렬
- Python
- class
- flask
- mongoose
- JavaScript
- 게임
- Dinosaur
- GIT
- Express
- OCR
- react
- Nest.js
- TypeScript
- Bull
- MySQL
- MongoDB
- jest
- nestjs
- Today
- Total
포시코딩
2월27일 - Nest.js에서 jest로 테스트 코드 작성하기 본문
개요
Controller - Service - Repository의 형태의 아키텍쳐로 이루어진
Nest.js 프로젝트에서 jest로 테스트 코드를 작성하려는데
아주 기본적인 틀만 가지고도 에러가 발생해
그 해결 과정에 대해 정리해보고자 한다.
일단 원래 보통 service에서 repository를 바로 inject 해오기 때문에
repository class가 따로 필요 없으나
여러 테이블을 join하거나 transaction을 쓰기에는 따로 구분 짓는 게 편하다고 생각해
custom repository를 만들게 되었다.
아래는 해당 repository의 코드다.
Repository
// ...import 생략
@Injectable()
export class MeetupsRepository extends Repository<Meetup> {
constructor(private dataSource: DataSource) {
super(Meetup, dataSource.createEntityManager());
}
async getMeetups(): Promise<Meetup[]> {
// ...생략
}
대충 이런 형태고
기본틀로 만든 테스트 코드는 다음과 같다.
repository.spec.ts
// ...import 생략
describe('MeetupsService', () => {
let repository: MeetupsRepository;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MeetupsRepository],
}).compile();
repository = module.get<MeetupsRepository>(MeetupsRepository);
});
it('should be defined', () => {
expect(repository).toBeDefined();
});
});
nest 명령어로 service를 만들 때 자동으로 만들어지는 service.spec.ts에서
service -> repository로 바꾼 것 뿐이다.
이제 내가 겪은 에러들과 그 해결 방법에 대해 하나하나 알아보자
문제 발생
Cannot find module ~ entity
entity의 경로를 찾지 못해 발생하는 에러다.
경로를 찾아가면
join.entity.ts에서 User를 가리키는 위치를 찾을 수 없다고 나온다.
이에 대해 검색하면 다들 절대 경로를 상대 경로로 바꾸라는 말을 할 것이다.
실제로 상대 경로로 바꿀 시 해결이 되긴 한다.
하지만 User뿐만 아니라 모든 module에서의 entity 경로를 상대경로로 죄다 바꿔줘야 한다.
이건 분명 잘못된 거고 다른 해결 방법이 있을 것이라 생각했다.
해결 방법
역시 package.json에서 jest에 대해 moduleNameMapper 옵션을 통해 해결할 수 있었다.
package.json
{
// ...생략
"jest": {
// ...생략
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/$1"
}
}
}
이렇게 변경 시 절대 경로에 대해서도 잘 작동하는 걸 볼 수 있다.
Nest can't resolve dependencies
위의 문제를 해결했지만 이번엔 다른 에러가 뜬다.
대충 종속성을 확인할 수 없다는 건데
이 문제를 해결하는데 진짜 오래 걸렸다.. 처음 해보니 뭐가 문제인지도 모르겠고
검색해 봐도 다 헛다리 짚고 있어서..
결론만 얘기하자면 그럼에도 결국 방법을 찾아냈고 해결할 수 있었는데 아래를 확인
해결 방법
DataSource와 관련해서 찾지 못하고 있으니
처음엔 해당 repository를 providers에 설정한 module의 import를 가져다 썼는데 그래도 안돼서
아예 근본적인 app.module의 import를 가져다 써보니 잘 되는 것을 확인할 수 있었다!
그중에서 위 사진의 빨간 네모 친 TypeOrmModule과 ConfigModule(TypeOrmModule에 필요하니)
두 모듈을 import 하면 해결된다.
repository.spec.ts
// ...import 생략
describe('MeetupsService', () => {
let repository: MeetupsRepository;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync({ useClass: TypeOrmConfigService }),
],
providers: [MeetupsRepository],
}).compile();
repository = module.get<MeetupsRepository>(MeetupsRepository);
});
it('should be defined', () => {
expect(repository).toBeDefined();
});
});
근데 저 노란 글씨가 거슬린다.. 이것도 해결해 보자
A worker process has failed to exit gracefully and has been force exited
작업 프로세스가 정상 종료 되지 않아 강제 종료 시켰다는 건데
좀 찾아본 결과 유추해 보면 테스트 실행 시 매 테스트 파일마다
DB를 새로 불러오는 코드로 작성되어 발생하는 것으로 보인다.
이것도 옵션을 통해 간단히 해결 가능하다.
해결 방법
jest를 실행할 때 --runInBand 옵션을 줄 수 있는데
해당 옵션의 역할은 테스트 실행 시 새로운 프로세스를 만들지 않고
처음 만들어진 프로세스에서 계속 테스트를 실행하게 한다는 것 같다.
적용해 보자.
package.json
"test:watch": "jest --watch --runInBand"
기존 유닛 테스트를 실행하는 명령어 맨 뒤에 --runInBand만 추가로 붙여주면 된다.
이제 어떠한 에러 없이 테스트가 통과되는 걸 확인할 수 있다.
추가 기록사항
Nest.js에서 Jest를 통한 테스트 코드 작성에 대해
비슷하면서도 다른 스타일의 가이드를 찾아 기록을 남긴다.
두 테스트 코드 모두 써봤는데 문제없이 잘 돌아가는 것을 확인
https://dev.to/tkssharma/unit-testing-and-integration-testing-nestjs-application-4d7a
https://medium.com/@exfabrica/nestjs-unit-and-e2e-tests-with-jest-825ba5033c6
여기도 설명이 괜찮아 추천
'TIL' 카테고리의 다른 글
3월1일 - git remote 다루기 (remote, upstream) (0) | 2023.03.02 |
---|---|
2월28일 - entity cascade 옵션 추가하기 (0) | 2023.02.28 |
2월25일 - ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1) (0) | 2023.02.26 |
2월24일 - @nestjs/throttler (0) | 2023.02.24 |
2월23일 - debounce, throttle (0) | 2023.02.23 |