[typescript] 테스트 더블을 활용한 통합 테스트 작성하기

소프트웨어 개발 프로세스에서 테스트 더블(test double)을 사용하여 통합 테스트(integration test)를 작성하는 것은 중요합니다. 테스트 더블을 활용하면 시스템의 다른 부분과의 의존성을 줄이고, 격리된 환경에서 코드를 테스트할 수 있습니다. 이러한 테스트 방법을 사용하면 실제 시스템과의 통합 전에 코드의 동작을 검증할 수 있습니다.

테스트 더블이란 무엇인가요?

테스트 더블은 실제 의존성을 가지는 객체를 대신하여 테스트에서 사용하는 객체입니다. 주로 다음과 같은 형태로 사용됩니다.

테스트 더블을 사용한 통합 테스트 작성하기

아래는 TypeScript와 Jest를 사용하여 테스트 더블을 활용한 통합 테스트를 작성하는 예시입니다.

먼저, 다음과 같이 userService.ts라는 사용자 서비스 코드가 있다고 가정해봅시다.

// userService.ts

import { User } from './models/user';
import { Database } from './database';

export class UserService {
  private db: Database;

  constructor(db: Database) {
    this.db = db;
  }

  async getUserById(id: number): Promise<User | null> {
    return this.db.query('SELECT * FROM users WHERE id = ?', [id]);
  }
}

그리고 테스트 코드를 작성할 때, Database 클래스의 실제 인스턴스 대신에 테스트 더블을 사용하여 getUserById 메서드를 테스트할 수 있습니다.

// userService.test.ts

import { UserService } from './userService';

class FakeDatabase {
  query(_sql: string, _params: any[]): Promise<any> {
    return Promise.resolve({ id: 1, name: 'John Doe' });
  }
}

test('getUserById returns user data', async () => {
  const userService = new UserService(new FakeDatabase());
  const user = await userService.getUserById(1);
  expect(user).toEqual({ id: 1, name: 'John Doe' });
});

위 예시에서는 FakeDatabase 클래스를 만들어 query 메서드를 가짜 응답을 반환하도록 하여 UserService를 테스트합니다.

테스트 더블을 사용하여 코드를 격리된 환경에서 테스트함으로써, 특정 모듈이나 서비스의 동작을 검증할 수 있습니다.

마무리

테스트 더블을 활용하여 통합 테스트를 작성하는 것은 소프트웨어 개발에서 신뢰할 수 있는 코드를 작성하는 데 중요한 요소입니다. 이를 통해 코드를 격리된 환경에서 테스트하고, 실제 시스템과의 통합 전에 코드의 안정성을 검증할 수 있습니다.

위 예시에서는 TypeScript와 Jest를 사용한 테스트 더블의 활용에 대해 살펴보았습니다. 테스트 더블을 활용하여 소프트웨어의 품질을 높이는 데에 도움이 되길 바랍니다.

참고 문헌: Jest Documentation, Testing TypeScript Applications with Jest


내용에 대한 추가적인 질문이 있으신가요? 무엇이든 도와드리겠습니다!