우아한테크코스 6기 백엔드 프리코스 - 1주차 미션
TODO list
지금까지 통과 한 테스트는 취소선으로 표시했다.
m1t01 - 1부터 9까지의 숫자 중 서로 다른 세 자리 숫자를 생성할 수 있어야 한다.
m1t02 - 서로 다른 세 자리 수가 아닌 사용자의 입력에 대해서는 IllegalArgumentException
을 발생시킨다.
m1t03 - IllegalArgumentException
이 발생하면 애플리케이션이 종료되어야 한다.
m1t04 - n개의 같은 수가 같은 자리에 있는 경우 n개의 스트라이크를 결과로 얻을수 있어야 한다. (n <= 3)
m1t05 - n개의 같은 수가 다른 자리에 있는 경우 n개의 볼을 결과로 얻을수 있어야 한다. (n <= 3)
m1t06 - 같은 수가 0개인 경우 낫싱이라는 결과를 얻을수 있어야 한다.
m1t07 - 사용자의 유효한 입력에 대한 적절한 결과를 출력할 수 있어야 한다.
m1t08 - 3스트라이크인 경우 게임이 종료된다.
m1t09 - 게임이 종료된 뒤 1을 입력받으면 새로운 게임이 진행된다.
m1t10- 게임이 종료된 뒤 2를 입력받으면 애플리케이션이 종료된다.
m1t11 - m1t01을 연속해서 여러 번 실행해도 유효한 세 개의 숫자를 생성해야 한다.
m1t06
낫싱이라는 결과는 볼이 0개, 스트라이크가 0개일 때 발생한다. m1t04, m1t05 테스트에서 이미 스트라이크와 볼 판정이 정확하다는 결과를 얻었다. 결국 낫싱은 자연스럽게 테스트된 것이라고 판단해서 일단 넘어가기로 했다.
m1t02
회원의 입력을 받아 BaseBallNumber
인스턴스를 생성하는 과정에서 IllegalArgumentException
이 발생함을 테스트한다. (UserInputHandler
의 생성자에 GameRule
객체가 빠졌다.)
테스트가 통과하도록 빠르게 구현했다. 이전의 비싼 리팩토링으로 여러 개의 객체에 책임을 분산했기 때문에 쉽게 구현할 수 있었다.
이 클래스는 사용자의 입력을 연산이 가능한 BaseBallNumber
인스턴스로 만들어준다. 검증에 대한 책임은 BaseBallNumber
에 있다.
살짝 졸면서 작성한 테스트를 다시 다듬었다.
m1t03
이 테스트에 필요한 객체는 GameRound
이다. 1라운드의 게임을 추상화 한 클래스이다. 입력된 값에 대한 적절한 값을 출력한다.
stdin으로부터 잘못된 입력을 받은 경우 GameRound
객체는 InvalidNumberException
예외를 던진다.
테스트 코드에 오류가 있어서 수정했다.
리듬 한 사이클의 보폭을 줄이기 위해 멀리 보지 않고 테스트를 통과시키는 것만 생각했다.
m1t07
정상적인 입력에 대해 적절한 값을 출력하는지 확인하는 테스트이다.
위의 테스트를 작성하기 위해 리다이렉션에 대해 학습하는 테스트를 작성했다.
m1t07은 한 번에 통과하기에는 부담스러워서 먼저 아래의 작은 테스트를 작성했다.
휴… 이번 테스트는 많은 우여곡절이 있었다.
NoSuchElementException
표준 입력 스트림을 내가 지정한 스트림으로 리다이렉션하는 코드가 포함된 테스트에서 NoSuchElementException
이 발생했다.
이 예외는 Scanner
가 더 이상 입력받을 값이 없을 때 발생한다.
System.setIn
메서드로 표준 입력 스트림을 바꾸지만 그 전에 생성된 Scanner
객체는 생성될 때의 스트림을지속적으로 참조한다.
미션의 라이브러리 속의 Console
코드를 보면 최초로 readLine
메서드가 호출될때 Scanner
인스턴스를 싱글톤으로 생성한다.
아래는 m1t07을 통과시키기 위해 코드를 작성하다가 깨진 테스트 중 하나인 m1t03을 수정한 것이다.
최종적으로 완성한 테스트는 다음과 같다.
이 테스트를 통과시키기 위해 작성한 GameRound
클래스는 게임의 한 라운드를 진행한다. 한 라운드는 3스트라이크가 나올때까지 계속 진행된다.
이 클래스의 역할은 입력에 대한 결과를(3스트라이크일때까지) 출력하는 것이다.
m1t08
m1t07 테스트를 수정 보완하다 보니 m1t08 테스트까지 포함하게 되었다.
m1t09 m1t10
해당 테스트는 미션과 함께 제공된 테스트를 활용했다.
이 테스트를 통과하기 위해 Application
을 아래와 같이 구현했다.
2일차 마무리
TDD책을 84페이지까지 읽고 흉내 내보면서 애플리케이션을 완성했다. 중간에 새로운 클래스를 도입하거나 새로운 메서드를 사용하여 기존의 구현과 테스트가 깨지면서 시간이 오래 걸리는 테스트도 있었다. 테스트를 작성하고, 통과하기만을 위한 구현을 반복했는데(애플리케이션 전체에 대한 생각은 전혀 하지 않았다) 진짜 모든 요구사항을 만족하는 애플리케이션이 완성되었다.
커피를 안 마시고 차를 마셨더니 잠이 쏟아져서 꽤 오래 결렸다. 😅
내일부터는 코드를 깨끗하게 정리하는 리팩토링이다.
Comments