🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Drizzle 테스트 전략 완벽 가이드 - 슬라이드 1/11
A

AI Generated

2025. 11. 4. · 54 Views

Drizzle 테스트 전략 완벽 가이드

Drizzle ORM의 효과적인 테스트 전략을 배워봅니다. 단위 테스트부터 통합 테스트까지, 실전에서 바로 활용할 수 있는 테스트 패턴을 소개합니다.


카테고리:TypeScript
언어:TypeScript
메인 태그:#Drizzle
서브 태그:
#ORM#Testing#Integration#UnitTest

들어가며

이 글에서는 Drizzle 테스트 전략 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. 테스트_데이터베이스_설정
  2. 스키마_마이그레이션_테스트
  3. Mock_데이터_생성_패턴
  4. CRUD_작업_단위_테스트
  5. 트랜잭션_테스트
  6. 관계형_쿼리_테스트
  7. 테스트_격리_패턴
  8. 페이지네이션_테스트
  9. 에러_처리_테스트
  10. 통합_테스트_with_API

1. 테스트 데이터베이스 설정

개요

테스트 전용 인메모리 SQLite 데이터베이스를 설정하여 빠르고 격리된 테스트 환경을 구축합니다.

코드 예제

import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';

const sqlite = new Database(':memory:');
export const testDb = drizzle(sqlite);

export function resetDb() {
  sqlite.exec('DROP TABLE IF EXISTS users');
}

설명

인메모리 데이터베이스는 실제 파일 시스템을 사용하지 않아 테스트 속도가 빠르며, 각 테스트마다 초기화가 가능합니다.


2. 스키마 마이그레이션 테스트

개요

테스트 환경에서 스키마를 동적으로 생성하고 마이그레이션을 검증합니다.

코드 예제

import { migrate } from 'drizzle-orm/better-sqlite3/migrator';

beforeAll(async () => {
  await migrate(testDb, {
    migrationsFolder: './drizzle'
  });
});

afterAll(() => {
  sqlite.close();
});

설명

beforeAll 훅에서 마이그레이션을 실행하여 테스트 전 스키마를 준비하고, 테스트 종료 시 연결을 정리합니다.


3. Mock 데이터 생성 패턴

개요

Factory 패턴을 사용하여 일관되고 재사용 가능한 테스트 데이터를 생성합니다.

코드 예제

export function createUser(override = {}) {
  return {
    name: 'Test User',
    email: 'test@example.com',
    age: 25,
    ...override
  };
}

const user = createUser({ name: 'John' });

설명

기본값을 제공하면서 필요한 부분만 오버라이드하여 다양한 시나리오의 테스트 데이터를 쉽게 만들 수 있습니다.


4. CRUD 작업 단위 테스트

개요

Drizzle의 CRUD 작업에 대한 단위 테스트를 작성하여 데이터베이스 로직을 검증합니다.

코드 예제

test('should create and find user', async () => {
  const newUser = createUser();

  await testDb.insert(users).values(newUser);
  const found = await testDb.select()
    .from(users).where(eq(users.email, newUser.email));

  expect(found[0].name).toBe(newUser.name);
});

설명

삽입 후 조회하여 데이터가 정확히 저장되고 검색되는지 확인합니다. 각 테스트는 독립적으로 실행됩니다.


5. 트랜잭션 테스트

개요

트랜잭션의 롤백과 커밋을 테스트하여 데이터 일관성을 보장합니다.

코드 예제

test('should rollback on error', async () => {
  await expect(testDb.transaction(async (tx) => {
    await tx.insert(users).values(createUser());
    throw new Error('Force rollback');
  })).rejects.toThrow();

  const count = await testDb.select().from(users);
  expect(count).toHaveLength(0);
});

설명

트랜잭션 중 에러 발생 시 모든 변경사항이 롤백되어 데이터베이스가 이전 상태를 유지하는지 검증합니다.


6. 관계형 쿼리 테스트

개요

조인과 관계형 데이터를 포함하는 복잡한 쿼리를 테스트합니다.

코드 예제

test('should fetch user with posts', async () => {
  const user = await testDb.insert(users)
    .values(createUser()).returning();

  const result = await testDb.select()
    .from(users).leftJoin(posts, eq(users.id, posts.userId));

  expect(result).toHaveLength(1);
});

설명

관계형 데이터의 조인이 올바르게 작동하는지 확인하여 복잡한 쿼리의 정확성을 보장합니다.


7. 테스트 격리 패턴

개요

각 테스트마다 데이터베이스를 초기화하여 테스트 간 간섭을 방지합니다.

코드 예제

beforeEach(async () => {
  await testDb.delete(users);
  await testDb.delete(posts);
});

test('isolated test 1', async () => {
  // 깨끗한 상태에서 시작
});

설명

beforeEach 훅으로 모든 테이블을 정리하여 각 테스트가 독립적으로 실행되고 다른 테스트의 영향을 받지 않습니다.


8. 페이지네이션 테스트

개요

limit과 offset을 사용한 페이지네이션 로직을 검증합니다.

코드 예제

test('should paginate correctly', async () => {
  await testDb.insert(users).values([
    createUser({ email: 'user1@test.com' }),
    createUser({ email: 'user2@test.com' })
  ]);

  const page = await testDb.select().from(users)
    .limit(1).offset(1);
  expect(page).toHaveLength(1);
});

설명

여러 데이터를 삽입한 후 limit과 offset이 정확히 작동하는지 확인하여 페이지네이션 구현을 검증합니다.


9. 에러 처리 테스트

개요

제약 조건 위반과 같은 데이터베이스 에러를 적절히 처리하는지 테스트합니다.

코드 예제

test('should handle unique constraint', async () => {
  const user = createUser();
  await testDb.insert(users).values(user);

  await expect(
    testDb.insert(users).values(user)
  ).rejects.toThrow();
});

설명

중복된 이메일 삽입 시 unique 제약 조건이 작동하여 에러가 발생하는지 확인합니다.


10. 통합 테스트 with API

개요

API 엔드포인트와 데이터베이스를 함께 테스트하는 통합 테스트를 작성합니다.

코드 예제

test('POST /users should create user', async () => {
  const res = await request(app)
    .post('/users')
    .send(createUser());

  expect(res.status).toBe(201);
  const dbUser = await testDb.select().from(users);
  expect(dbUser).toHaveLength(1);
});

설명

API 호출이 실제로 데이터베이스에 데이터를 저장하는지 확인하여 전체 플로우가 정상 작동하는지 검증합니다.


마치며

이번 글에서는 Drizzle 테스트 전략 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#Drizzle #ORM #Testing #Integration #UnitTest

#Drizzle#ORM#Testing#Integration#UnitTest#TypeScript

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스