E2E 테스트를 작성하고 실행했는데 이상하게 연결 오류가 발생했다. 연결 후 데이터베이스 정리 코드를 찾은 다음 다시 테스트를 했는데 다른 오류가 등장했다. Mongoose는 TypeORM과 다른 점이 많아서 이에 대해 적어본다!
데이터베이스 연결
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | describe('Authentication E2E Test', () => { let app: INestApplication; let createUserDto: CreateUserDto; let credentials: { email: string; password: string; }; beforeEach(async () => { createUserDto = { name: '가나다', password: '1234Aa!@', email: 'ganada@naver.com', role: Role.USER, }; credentials = { email: 'ganada@naver.com', password: '1234Aa!@', }; const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = moduleFixture.createNestApplication(); await app.init(); }); describe('signUp', () => { it('should throw BadRequestException for an invalid name.', async () => { createUserDto.name = '가나'; await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.BAD_REQUEST); }); it('should throw BadRequestException for an invalid password.', async () => { createUserDto.password = '1234'; await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.BAD_REQUEST); }); it('should throw BadRequestException for an invalid email.', async () => { createUserDto.email = 'ganada'; await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.BAD_REQUEST); }); it('should create a user.', async () => { const response = await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.CREATED); const body = response.body; expect(body.password).not.toBe(createUserDto.password); expect(body.email).toBe(createUserDto.email); }); it('should throw ConflictException for a duplicate email.', async () => { await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.CREATED); await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.CONFLICT); }); }); describe('signIn', () => { it('should throw BadRequestException for an invalid email.', async () => { credentials.email = 'sfaslkf@naver.com'; await request(app.getHttpServer()) .post('/auth/signin') .send(credentials) .expect(HttpStatus.BAD_REQUEST); }); it('should throw BadRequestException for an invalid password.', async () => { credentials.password = '24391!@svz'; await request(app.getHttpServer()) .post('/auth/signin') .send(credentials) .expect(HttpStatus.BAD_REQUEST); }); it('should sign in a user.', async () => { await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.CREATED); const response = await request(app.getHttpServer()) .post('/auth/signin') .send(credentials) .expect(HttpStatus.OK); const headers = response.headers; expect(headers).toBeDefined(); const cookies = headers['set-cookie'].map( (cookie: string) => cookie.split(';')[0], ); const accessToken = cookies .find((cookie: string) => cookie.includes('access_token')) .split('=')[1]; const refreshToken = cookies .find((cookie: string) => cookie.includes('refresh_token')) .split('=')[1]; const body = response.body; expect(accessToken).toBeDefined(); expect(refreshToken).toBeDefined(); expect(body.email).toBe(credentials.email); }); }); describe('signOut', () => { it('should sign out a user.', async () => { await request(app.getHttpServer()) .post('/auth/signup') .send(createUserDto) .expect(HttpStatus.CREATED); let response = await request(app.getHttpServer()) .post('/auth/signin') .send(credentials) .expect(HttpStatus.OK); const headers = response.headers; expect(headers).toBeDefined(); let cookies = headers['set-cookie']; response = await request(app.getHttpServer()) .post('/auth/signout') .set('Cookie', cookies) .expect(HttpStatus.NO_CONTENT); cookies = response.headers['set-cookie'].map( (cookie: string) => cookie.split(';')[0], ); const accessToken = cookies .find((cookie: string) => cookie.includes('access_token')) .split('=')[1]; const refreshToken = cookies .find((cookie: string) => cookie.includes('refresh_token')) .split('=')[1]; expect(accessToken).toBe(''); expect(refreshToken).toBe(''); }); }); afterEach(async () => { await mongoose.connection.dropCollection('users'); await app.close(); }); }); | cs |
코드를 보면 Mongoose 패키지 자체를 가져온 다음 각 테스트 종료 후 사용자 컬렉션을 비우는 dropCollection() 메서드를 호출한다. 하지만 [ExceptionHandler] Unable to connect to the database. Retrying (1)... 오류가 발생했다!
TypeORM에서 데이터베이스와 상호작용하기 위해 app.get() 메서드로 TypeORM 패키지의 DataSource를 가져온 것처럼 Mongoose 패키지에서 비슷한 메서드를 찾아야 했다. 검색을 통해 알아보니 mongoose.connect() 메서드가 MongoDB와 기본 연결을 연다고 하며 URI를 인자로 가진다.
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 31 32 | // common.factory.ts export const buildDatabaseUri = () => { return `mongodb://${process.env.DB_USERNAME}:${process.env.DB_PASSWORD}@${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_DATABASE}`; }; // auth.e2e-spec.ts describe('Authentication E2E Test', () => { let app: INestApplication; ... beforeEach(async () => { ... const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = moduleFixture.createNestApplication(); await app.init(); }); ... afterEach(async () => { // 테스트 환경 데이터베이스 URI를 가져온다. mongoose.connect(buildDatabaseUri()); await mongoose.connection.dropCollection('users'); await app.close(); }); }); | cs |
테스트를 다시 실행했는데 연결 오류는 사라졌는데 MongoError: ns not found 오류가 나왔다... 이건 뭐지?
데이터베이스 정리
데이터베이스는 정리가 되는데 왜 이런 오류가 발생했는지 알아보니 컬렉션이 없어서 발생하는 오류라고~ 따라서 해결책은 자연스럽게 컬렉션을 생성하면 된다!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | describe('Authentication E2E Test', () => { ... afterEach(async () => { mongoose.connect(buildDatabaseUri()); // 컬렉션의 모든 도큐먼트를 제거한다. await mongoose.connection.dropCollection('users'); // 컬렉션을 생성한다. await mongoose.connection.createCollection('users'); await mongoose.disconnect(); await app.close(); }); }); | cs |
테스트가 성공적으로 통과된다!
update: 2024.02.16
댓글 없음:
댓글 쓰기