-
숫자야구게임 구현(1)공부/자바 플레이그라운드 with TDD, 클린코드 2022. 2. 13. 20:25
TDD가 익숙치 않아 프로덕션 코드를 구현하고 단위 테스트를 적용시켜 버렸다..
숫자야구게임 피드백을 보고 다시 구현할 것이다.
BaseBallGameTest
public class BaseBallGameTest { @ParameterizedTest @CsvSource({ "845,낫싱", "891,1볼", "137,포볼", "123,1볼 1스트라이크", "723,2스트라이크", "713,3개의 숫자를 모두 맞히셨습니다! 게임 종료" }) void baseBallGameCoreTest(String input, String expected) throws Exception { BaseBallGameCore bbgc = new BaseBallGameCore("713"); bbgc.calc(input); assertThat(bbgc.getStatus()).contains(expected); } @Test void baseBallGameCoreExceptionTest() throws Exception { Throwable thr = catchThrowable(() -> new BaseBallGameCore("71")); assertThat(thr).hasMessageContaining("적어도 3자리 이상의 길이를 입력해 주십시오."); } @Test void baseBallGameCoreStrikeExceptionTest() throws Exception { BaseBallGameCore bbgc = new BaseBallGameCore("713"); Throwable thr = catchThrowable(() -> bbgc.strike("12")); assertThat(thr).hasMessageContaining("입력한 값의 길이와 정답의 길이가 다릅니다."); } }
BaseBallGameCore
public class BaseBallGameCore { private String answer; protected int ball = 0; protected int strike = 0; public BaseBallGameCore(String answer) throws Exception { if (!validateLength(answer)) throw new Exception("적어도 3자리 이상의 길이를 입력해 주십시오."); this.answer = answer; } private boolean validateLength(String answer) { return answer != null && answer.length() >= 3; } public boolean strike(String input) throws Exception { if (answer.length() != input.length()) throw new Exception("입력한 값의 길이와 정답의 길이가 다릅니다."); resetStatus(); if (answer.equals(input)) { strike = answer.length(); return true; } calc(input); return false; } private void resetStatus() { ball = 0; strike = 0; } public void calc(String input) { for(int i=0; i<input.length(); i++) { calcStrikeAndBall(input.charAt(i), i); } } private void calcStrikeAndBall(char input, int index) { if(calcStrike(input, index)) { strike++; return; } if(calcBall(input, index)) { ball++; return; } } private boolean calcStrike(char input, int index) { return equals(input, answer.charAt(index)); } private boolean equals(char c1, int c2) { return c1 == c2; } private boolean calcBall(char input, int index) { return Stream.of(remains(index).split("")) .map(s -> s.charAt(0)) .filter(c -> c == input) .count() > 0; } private String remains(int index) { return answer.substring(0, index) + answer.substring(index + 1); } public String getStatus() { StringBuilder sb = new StringBuilder(); if(ball == answer.length()) return "포볼"; if(strike == answer.length()) return String.format("%d개의 숫자를 모두 맞히셨습니다! 게임 종료", strike); if(ball > 0) sb.append(ball + "볼 "); if(strike > 0) sb.append(strike + "스트라이크"); if(sb.length() <= 0) return "낫싱"; return sb.toString(); } }
영상 시청 후
더보기- 요구사항 분석으로 TodoList를 작성
- 필요한 기능 을 상세히
- 기능 단위로 *Test.java 작성!!!!!!!!
- 테스트를 하기 쉬운 코드를 먼저 (UI, DB, 랜덤은 어려움)
- 테스트 코드 먼저 실패하도록 작성
- 컴파일 에러 해결하기위해 테스트 작성 -> 코드 생성 역순으로 하는것에 익숙해지자
- 테스트 코드를 성공하도록 프로덕션 코드 작성
- 리팩토링
- IntelliJ 의 단축키 완전 대박
- 오른쪽 클릭 Reactor 에서 단축키 따로 외우자 굿~ - 하드코딩 하지말고 상수값 사용
- commit 단위는 하나의 테스트코드 + 프로덕션코드를 뭉탱이로 올리고, 테스트 명칭을 feature 로 commit 하면 될듯
- 큰 덩어리는 작은 덩어리로 쪼개서 테스트 가능하도록 연습
- 일단 클래스 메서드, static으로 기능작성 TDD 편하게 (상태를 가지면 복잡하니)
- 클래스 메서드 작성할 때 같은 클래스의 다른 인스턴스에 직접적으로 멤버변수에 접근하지말고 객체에 메세지를 전달한다는 생각으로 이또한 메서드로 빼자
- Enum 내부 메서드를 활용해 Enum에도 메세지를 전달하는 메서드를 이용하자
- 원시값, 문자열를 감싸서 유효성 검사를 하는등 클래스분리도 해보자
- 같은 클래스의 값을 검사할 때 if문을 제거하기위해 인터페이스로 메서드를 override하는 방법도 좋다
직접 구현하고 다시 게시글 작성하자
'공부 > 자바 플레이그라운드 with TDD, 클린코드' 카테고리의 다른 글
자동차 경주 게임 피드백 영상 시청 후 (0) 2022.03.02 숫자야구게임 구현(2) - 요구사항 작성, TDD 적용 (0) 2022.02.16 단위 테스트 실습 - 문자열 계산기 (0) 2022.02.13 객체 지향 생활 체조 원칙 (0) 2022.02.03