Testing/Jest

[Test] Mock, Stub, Fake : 테스트의 세가지 핵심 개념

닉네임없음ㅎ 2024. 11. 28. 21:04

 

테스트 코드 작성에 대한 공부를 하다보면 Mock, Stub, Fake 라는 용어를 자주 접하게 된다.

이들은 모두 테스트할 때 의존성을 해결하기 위해 사용되며, 
특히 외부 디펜던시( 데이터베이스, 로깅 등..)를 테스트 환경에서 대체하기 위해 활용된다 ! 

*왜 의존성을 대체하는 객체를 사용하는가 ? 
-> 테스트를 작성할 때, 실제 의존성을 그대로 사용하는 방법도 있지만, 
테스트 실행 속도가 느려지고 테스트가 의존성에 취약해질 가능성이 있다 ! 

(예를들어,, 데이터베이스에 연결된 테스트는 
네트워크 상태나 데이터베이스 상태에 따라 결과가 달라질 수 있는.....)

따라서 의존성을 제거하고, 대체 객체를 사용해서 안정적인 테스트 환경을 구성하는 것이 중요함. 



* Mock & Stub & Fake 

1. Mock 
-> Mock은 상호작용을 검증하는 객체로, 행위를 테스트한다. 
주요 목적은 테스트 대상 코드가 의존성과 올바르게 상호작용하는지 확인을 하는 것임. 

예를들어,
특정 함수가 호출 되었는지 ? 
몇번 호출되었는지?
어떤 파라미터로 호출되었는지 ? 등을 검증한다.

 

예시)

const mockLogger = {
  log: jest.fn(),
};

function exampleFunction(logger) {
  logger.log("Test message");
}

exampleFunction(mockLogger);

// logger.log가 정확히 호출되었는지 확인
expect(mockLogger.log).toHaveBeenCalledWith("Test message");




2. Stub 
-> 함수나 객체의 간소화된 버전으로 미리 정의된 값을 반환하는 객체로, 테스트를 위한 동작을 제공하는데 초점을 둔다. 

 

예시)

const stubAuthService = {
  isAuthenticated: () => true,
};

function checkAuthentication(authService) {
  return authService.isAuthenticated();
}

expect(checkAuthentication(stubAuthService)).toBe(true);




3. Fake 
-> 실제 객체를 간단하게 구현한 형태로 Stub과 달리 Fake는 실제로 동작한다.
단, 복잡한 의존성을 제거하기 위해서 축소된 기능을 제공한다 ! 

예시)

class FakeDatabase {
  private store = new Map<string, string>();

  save(key: string, value: string) {
    this.store.set(key, value);
  }

  get(key: string) {
    return this.store.get(key);
  }
}

const fakeDB = new FakeDatabase();
fakeDB.save("key1", "value1");
expect(fakeDB.get("key1")).toBe("value1");

 

 

이렇게 적절한 대체 객체를 사용하여 효율적인 테스트를 작성할 수 있다!