자바스크립트 TDD에서의 테스트 더블 활용 방법

테스트 주도 개발(Test-Driven Development, TDD)은 소프트웨어 개발 방법론 중 하나로, 테스트 코드를 먼저 작성한 후에 해당 테스트를 통과하는 코드를 작성하는 방식입니다. 이것은 소프트웨어의 품질 향상과 유지보수의 용이성을 높여주는 장점을 가지고 있습니다. 자바스크립트에서도 TDD를 적용하여 품질 좋은 코드를 작성할 수 있습니다.

TDD에서 중요한 요소 중 하나는 테스트 더블(Test Double)입니다. 테스트 더블은 실제 의존성을 가진 객체를 대체하여 테스트에서 사용되는 가짜 객체입니다. 테스트 더블은 다음과 같은 목적으로 사용될 수 있습니다.

스텁(Stub)

스텁은 테스트 더블의 일종으로, 특정 메서드의 반환값이나 동작을 가짜로 대체하여 테스트가 정상적으로 진행될 수 있게 합니다. 예를 들어, 외부 API를 호출하는 코드의 테스트를 작성할 때, 실제 API를 호출하지 않고 스텁을 주입하여 특정 값을 반환하게 할 수 있습니다.

class ExternalAPI {
  fetchData() {
    // 실제로는 외부 API를 호출하여 데이터를 가져옴
  }
}

class MyClass {
  constructor(externalAPI) {
    this.externalAPI = externalAPI;
  }

  getDataFromExternalAPI() {
    const data = this.externalAPI.fetchData();
    // 데이터 처리 로직
    return processedData;
  }
}

// 테스트 코드
const stubAPI = {
  fetchData: () => {
    return fakeData; // 가짜 데이터 반환
  }
};
const myClass = new MyClass(stubAPI);
const result = myClass.getDataFromExternalAPI();
// result와 예상 결과 비교

모의 객체(Mock)

모의 객체는 실제 객체와 유사한 동작을 가지면서도, 호출 여부나 전달된 인자를 검증할 수 있는 테스트 더블입니다. 예를 들어, 메일을 전송하는 클래스의 테스트를 작성할 때, 모의 객체를 사용하여 메일 전송 메서드가 제대로 호출되는지를 검증할 수 있습니다.

class EmailSender {
  sendEmail(to, subject, body) {
    // 이메일 전송 로직
  }
}

class MyMailer {
  constructor(emailSender) {
    this.emailSender = emailSender;
  }

  sendWelcomeEmail(user) {
    this.emailSender.sendEmail(user.email, 'Welcome', 'Hello!');
  }
}

// 테스트 코드
const mockEmailSender = {
  sendEmail: jest.fn() // 모의 메서드로 대체
};
const myMailer = new MyMailer(mockEmailSender);
myMailer.sendWelcomeEmail({ email: 'test@example.com' });
expect(mockEmailSender.sendEmail).toHaveBeenCalledWith('test@example.com', 'Welcome', 'Hello!');

스파이(Spy)

스파이는 실제 객체와 유사한 동작을 가지면서, 호출된 횟수나 호출된 인자 값을 기록하고 검증할 수 있는 테스트 더블입니다. 스파이는 메서드가 호출되었는지, 얼마나 자주 호출되었는지 등을 확인하고 테스트의 일부로 활용할 수 있습니다.

class MathUtils {
  sum(a, b) {
    return a + b;
  }
}

// 테스트 코드
const mathUtils = new MathUtils();
const sumSpy = jest.spyOn(mathUtils, 'sum');
const result = mathUtils.sum(2, 3);
expect(sumSpy).toHaveBeenCalled();
expect(sumSpy).toHaveBeenCalledWith(2, 3);
expect(result).toBe(5);

테스트 더블을 활용하여 자바스크립트 TDD를 수행하면, 의존성이 있는 코드의 테스트를 더 쉽고 견고하게 작성할 수 있습니다. 이로써 코드의 품질을 향상시키고 유지보수를 용이하게 할 수 있습니다.

참고 자료: