소프트웨어 개발 프로세스에서 테스트 더블(test double)을 사용하여 통합 테스트(integration test)를 작성하는 것은 중요합니다. 테스트 더블을 활용하면 시스템의 다른 부분과의 의존성을 줄이고, 격리된 환경에서 코드를 테스트할 수 있습니다. 이러한 테스트 방법을 사용하면 실제 시스템과의 통합 전에 코드의 동작을 검증할 수 있습니다.
테스트 더블이란 무엇인가요?
테스트 더블은 실제 의존성을 가지는 객체를 대신하여 테스트에서 사용하는 객체입니다. 주로 다음과 같은 형태로 사용됩니다.
- 페이크(fake): 실제 동작 로직은 포함하지 않으며, 테스트 목적으로만 사용됩니다.
- 스텁(stub): 특정 값을 반환하거나 특정 동작을 수행합니다.
- 스파이(spy): 호출된 정보에 대한 기록을 남기고, 호출된 메서드의 인자나 반환값 등을 반환합니다.
- 모의 객체(mock): 특정 동작이 호출되는지 여부를 확인하고, 특정 동작이 수행되었을 때의 결과를 설정할 수 있습니다.
테스트 더블을 사용한 통합 테스트 작성하기
아래는 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
내용에 대한 추가적인 질문이 있으신가요? 무엇이든 도와드리겠습니다!