728x90
반응형
SMALL
🚀 Next.js에서 Supabase 실무 통합 테스트 환경 구축하기 (Vitest)
Next.js 프로젝트에서 Supabase 실제 DB를 대상으로 통합 테스트(Integration Test)를 작성할 때, 가장 큰 걸림돌은 환경 변수(process.env) 로딩 순서입니다. 본 가이드에서는 Vitest와 dotenv를 활용해 이 문제를 해결하고 실제 DB 연동까지 확인하는 완벽한 워크플로우를 소개합니다.
🛠️ 1. 필수 패키지 설치
테스트 환경을 구축하기 위해 필요한 핵심 도구들을 설치합니다. Next.js의 경로 별칭(@/)과 브라우저 환경(jsdom)을 지원하는 패키지들입니다.
PowerShell
npm install -D vitest @vitejs/plugin-react vite-tsconfig-paths jsdom dotenv @testing-library/jest-dom
⚙️ 2. Vitest 설정 (환경 변수 문제 해결)
Next.js 환경에서 import 문은 코드 실행보다 먼저 처리되어 환경 변수가 undefined로 뜨는 경우가 많습니다. 이를 방지하기 위해 setupFiles를 활용합니다.
vitest.config.ts 생성
TypeScript
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import path from 'path';
export default defineConfig({
plugins: [react(), tsconfigPaths()],
test: {
environment: 'jsdom',
globals: true,
// [핵심] 테스트 실행 직전 환경 변수를 먼저 로드합니다.
setupFiles: [path.resolve(__dirname, './vitest.setup.ts')],
},
});
vitest.setup.ts 생성
.env.test 파일을 읽어 process.env에 강제로 주입하는 셋업 파일입니다.
TypeScript
import { config } from 'dotenv';
import path from 'path';
// .env.test 파일을 로드하여 테스트 프로세스에 할당합니다.
config({ path: path.resolve(__dirname, '.env.test') });
📝 3. 환경 변수 및 스크립트 설정
테스트 전용 DB 정보를 관리하기 위해 .env.test 파일을 별도로 생성하는 것을 권장합니다.
.env.test 파일 예시
코드 스니펫
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY=your-secret-key
package.json 스크립트 추가
JSON
"scripts": {
"test": "vitest --config ./vitest.config.ts --mode test"
}
🧪 4. 실제 DB 통합 테스트 코드 작성
테스트 대상 파일(supabaseService.ts)과 같은 위치에 .test.ts 파일을 생성하여 관리합니다.
supabaseService.ts (원본 코드)
TypeScript
import { supabaseAdmin } from '@/lib/supabaseServer';
export const supabaseService = {
async save(content: string) {
const { data, error } = await supabaseAdmin
.from('ko_grammer') // 테이블명 확인 필수
.insert([{ content }])
.select()
.single();
if (error) {
console.error('DB 저장 실패:', error.message);
return { success: false, error };
}
return { success: true, data };
}
};
supabaseService.test.ts (테스트 코드)
실제 네트워크 통신이 발생하므로 타임아웃을 넉넉히 설정하고, 테스트 후 데이터를 삭제하는 Cleanup 로직을 포함합니다.
TypeScript
import { afterAll, describe, expect, it } from 'vitest';
import { supabaseAdmin } from '@/lib/supabaseServer';
import { supabaseService } from './supabaseService';
describe('supabaseService.save 실제 DB 통합 테스트', () => {
const TEST_CONTENT = '테스트 코드에서 보낸 실제 데이터입니다.';
// 테스트 종료 후 생성된 데이터를 삭제하여 DB 정결 유지
afterAll(async () => {
await supabaseAdmin
.from('ko_grammer')
.delete()
.eq('content', TEST_CONTENT);
});
it('실제 Supabase DB에 데이터를 저장하고 결과를 반환해야 한다', async () => {
// 1. 함수 실행
const result = await supabaseService.save(TEST_CONTENT);
// 2. 응답 값 검증
expect(result.success).toBe(true);
expect(result.data?.content).toBe(TEST_CONTENT);
// 3. DB 직접 조회 교차 검증
const { data } = await supabaseAdmin
.from('ko_grammar')
.select()
.eq('id', result.data?.id)
.single();
expect(data).not.toBeNull();
expect(data?.content).toBe(TEST_CONTENT);
}, 10000); // 네트워크 통신 고려 타임아웃 10초 설정
});
728x90
반응형
LIST
'나의 주니어 개발 일기 > REACT' 카테고리의 다른 글
| React 경로 alias 설정하기 (@ 절대경로로 import 깔끔하게 정리) (0) | 2025.12.23 |
|---|---|
| React 페이지 라우팅 완벽 정리 – Link, useNavigate, 동적 경로, URL 파라미터까지 (0) | 2025.11.11 |
| [REACT] Context 로 전역 상태 관리하기 (0) | 2025.07.16 |
| [REACT] useMemo로 랜더링 최적화 하기 (6) | 2025.07.14 |
| [REACT] useReducer (0) | 2025.07.03 |