현재 진행하고 있는 개인 프로젝트에서는 Nest.js + MongoDB + Prisma ORM
을 사용하고 있다. Prisma에서 MongoDB를 사용하기 위해서는 MongoDB가 Replica Set으로 설정되어있어야 한다.
Prisma에서 MongoDB를 사용할때 Replca Set을 강제하는 이유는, Prisma의 Nested Query를 통한 Write를 진행할때 Partial Write를 방지하기 위해서 내부적으로 MongoDB Transaction을 사용하기 때문이다.
MongoDB에서는 Transaction을 사용하기 위해서 MongoDB가 Replica Set으로 설정되어있을 수 있도록 강제하기 때문에, Prisma에서 MongoDB를 Replica로 사용하는것이 강제되는것이다.
Prisma는 Single Replica가 가능한 Dockerfile을 제공한다.(링크). 만약 Intel MacOS를 사용하거나, 윈도우를 사용한다면, 개인적으로 Testingcontainers
+ Prisma 제공 Replica Image
를 사용해보는걸 추천한다. 하지만 이는 amd/64 전용 이미지 이므로, Apple Silicon을 활용하고 있는경우에는 사용이 불가능하다. 그렇기 때문에 선택한 방법은, MongoDB Atlas를 활용하는 것이었다.(MongoDB Atlas에 대한 자세한 이야기는 생략한다)
간단하게 signup, singin 서비스를 작성하고 유닛테스트 코드를 작성한다. Prisma.schema
파일을 보면 알 수 있듯이, datasource URL을 .env
파일의 DATABASE_URL
환경변수를 사용하는것을 볼 수 있다.(기본값이다)
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
Prisma Module의 경우에는 Global Module로 설정이 되어있다.
현재 개발을 위해서 사용하는 Database에서 테스트를 진행할 수 없기 때문에, 테스트를 진행할때는 다른 Database를 사용하고자 하였다. 이를 위해서는 개발할때 사용하는 .env
파일과 다른 .env
파일을 사용해야한다. 기존 코드베이스를 변경하고 테스트 코드에 대한 추가 확장만 진행하고자 하였다.
이를 위해서는 Unit Test를 위한 jest config file을 추가하였다.(test/jest.unit.json)
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": "../src",
"testEnvironment": "node",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"collectCoverageFrom": ["**/*.(t|j)s"],
"moduleNameMapper": {
"test/(.*)$": "<rootDir>/../test/$1",
"src/(.*)$": "<rootDir>/$1",
"^@app/(.*)$": "<rootDir>/app/$1",
"^@infrastructure/(.*)$": "<rootDir>/infrastructure/$1",
"^@domain(.*)$/": "<rootDir>/domain/$1"
},
"setupFiles": ["<rootDir>/../test/test-env.ts"]
}
여기서 주목할 것은, setupFiles
라는 필드이다. Jest 공식문서에서 setupFiles
를 찾아보면, 각각의 test suit가 실행되기 이전에 한번씩 실행되는 파일들의 경로를 Array 인자값으로 받는것을 볼 수 있다.
위 jest config file에서는 test-env.ts
를 각 테스트 슈트마다 호출하여 테스트 환경 전용 .env
파일을 가져오도록 설정하였다
// test/test-env.ts
import * as dotenv from 'dotenv';
dotenv.config({
path: `${__dirname}/../test.env`,
});
그리고 위 테스트 코드를 사용하여 단위테스트를 진행하는 test:unit
scripts를 생성한다.
//package.json
"test:unit": "jest --config ./test/jest.unit.json",
// test.env
DATABASE_URL="mongodb+srv://(user):(password)@(atlas url)/(databasename)-test?retryWrites=true&w=majority"
JWT_TOKEN="TOKEN"
단일 파일로 실행했을떄도 잘 실행되는것을 확인할 수 있다.