[공부] interface 활용기

오영선·2023년 11월 1일
0

우아한 테크 프리코스 6주차 - 1차시 내용을 회고하며 정리한 내용입니다

1주차<숫자야구게임>의 코드 리뷰 하러 다니다가, 테스트 코드 작성시 나의 의도대로 완벽하게 수행되지 않는 함수( 예를들어, 랜덤으로 숫자를 생성하는 기능 ) 를 포함하는 함수에서 어떻게 테스트를 작성할 수 있을까?
를 고민하며 적어본 글입니다!

아직 부족한 점도 많고 차차 배우는 중이니, Mock()을 사용하지 않고 테스트를 작성하기 위한 자그마한 팁(..?) 정도로 생각하고 읽어주시면 감사하겠습니다.

1주차 저의 코드입니다. 많이 엉성하네요
위의 RandomGenerator는, 컴퓨터의 숫자 3자리수를 생성하는 기능을 합니다.
그러나 이 클래스는 자체적으로 랜덤의 수를 뽑아내기 때문에, 저희가 원하는 숫자로'만' 출력하기는 불가능 합니다.


다음은 위의 클래스를 사용하는 함수입니다.
1주차에서 저는 결국 위의 playGame() 에 대한 테스트를 작성하지 못하고 제출했습니다.
List<Ball> computer = randomGenerator.getComputer(); 에 대한 수를 지정하지 않고서는 정상적으로 값이 일치하는지 확인할 방법이 없기 때문입니다.

위의 기능을 리팩토링 해봅시다


저는 이 문제를 해결하기 위해 interface를 활용하기로 했습니다.

인터페이스(interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미합니다.

이로 인해 우리는 make_ball()를 사용하는 테스트를 작성할때,
RandomGenerator generator= 가 아닌 Generator gerator= 로 타입을 지정할 수 있는 이득을 었었습니다!

이제 이 이득(?) 이 어떻게 테스트코드에 활용되는지 알아봅시다.


사용자가 반드시 "111" 이라고 입력할 것을 예상하여, STRIKE Test를 위해 Generator를 상속받아 111을 생성하는 ONEONEONEGenerator를 작성하였습니다.

이제 이 클래스를 사용해 controller단위의 테스트를 작성해 봅시다!


(이해를 돕기 위해 위의 playGame()함수에서 strike의 개수를 세는 함수로 간단하게 변경하였습니다.)
인자로 Generator라는 부모 타입을 받아, 컴퓨터의 balls를 만드는 부분 입니다.

우리가 Generator를 인터페이스로 분리하였기 때문에, 랜덤숫자(1-9)사이를 생성하는 Generator와 지정된 수(1-1) 만 생성하는 Generator를 분리하여, 테스트 시에 Mock없이도 지정된 결과를 출력할 수 있도록 하였습니다

결론

  • Test를 위해 interface를 활용 해보자
  • 부모를 만들어 자식을 분리하면, 함수의 재사용성과 결합도도 낮출수 있었다

0개의 댓글