자동차 경주 피드백
- 우아한테크코스
- 2021. 6. 9. 20:14
목적
이전 미션의 PR들을 보고 있다. 레벨 2가 끝나가는 시점에 잘 지켜지는 피드백도 있고, 그렇지 않은 피드백도 있다. 잘 이해가 되는 개념도 있고 그렇지 않은 개념도 있다. 그런 것들을 정리해 보려고 한다.
객체를 객체스럽게 사용해라
이번 지하철 미션에서도 한번 피드백을 받았다. 한번 더 리마인드 하면 좋을 것 같다.
Line line = findById(id);
Sections sections = line.getSections();
List<Section> deleteSections = sections.deleteSection(stationId);
Line line = findById(id);
List<Section> deleteSections = line.deleteSection(stationId);
- 객체는 캡슐화된 상태와 외부에 노출되어 있는 행동을 가지고 있다.
- 이를 토대로 다른 객체와 메시지를 주고 받으면서 협력한다.
- 객체는 메시지를 받으면 그에 따른 로직을 수행하게 되고, 이를 통해 객체 스스로 내부의 상태값을 변경한다.
- getter로 데이터를 꺼내 로직을 처리하지 말고, 객체에 메시지를 보내 일을 하도록 리팩토링 한다.
https://woowacourse.github.io/javable/post/2020-04-28-ask-instead-of-getter/
단위 테스트하기 어려운 코드를 단위 테스트하기
자동차 경주의 요구사항 중 아래와 같은 요구사항이 있다.
- 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다.
일반적으로 테스트의 구조는 given/when/then 형식으로 짜여진다. 그러나 given을 통제할 수 없는 상황에서 어떻게 테스트를 해야하는지 많은 고민이 있었다. 이 부분은 자동차 경주 피드백의 PR 대부분에서 질문으로 들어가 있었다. 그래서 정리해보려고 한다.
전략패턴을 사용한다.
@ParameterizedTest
@DisplayName("랜덤 값이 4 이상일 경우 전진하고 3 이하의 값이면 멈춘다.")
@CsvSource(value = {"1,1,1:0", "1,6,3:1", "6,5,7:3"}, delimiter = ':')
public void move_랜덤_값이_4_이상일_경우_전진하고_3_이하의_값이면_멈춘다(String input, int expected) {
int[] inputs = Arrays.stream(input.split(",")).mapToInt(Integer::parseInt).toArray();
Car car = new Car("포비", new CarMoveCondition() {
private int[] randomNumbers = inputs;
private int index = 0;
@Override
public boolean isMovable() {
return randomNumbers[index++] >= 4;
}
});
for (int i = 0; i < inputs.length; i++) {
car.move();
}
assertEquals(expected, car.getPosition());
}
그때에는 움직임을 MoveCondition으로 추상해서 구현했었다. 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다. 라는 요구사항이 변하지 않는다면 move()에 파라미터로 값을 받는 것도 괜찮았을 것 같다. 파라미터를 추가하는 것 외에 상속을 사용한다. 라는 해결방법도 있는데 그것은 javable 포스팅에 자세히 나와 있다.
- 파라미터를 추가한다.
- 상속을 사용한다.
https://woowacourse.github.io/javable/post/2020-04-28-test-without-method-change/
테스트 픽스처
'테스트만을 위해서 프로덕션 코드가 추가되는 것이 옳은가' 이게 부제목이 될 듯하다. 피드백에 테스트를 위한 편의 메서드를 구현코드에 구현하지 말라고 한다. 테스트 픽스처를 활용 해 보자.
테스트 픽스처
- 테스트를 반복적으로 수행할 수 있게 도와주고 매번 동일한 결과를 얻을 수 있게 도와주는 기반이 되는 상태나 환경
- 여러 테스트에서 공용으로 사용할 수 있는 테스트 픽스처는 테스트의 인스턴스 변수 혹은 별도의 클래스에 모아본다.
Car에 setPosition()을 만들지 말고, 테스트 클래스 내에 이 환경을 만들 수 있는 테스트 픽스처를 추가하자
private Car createCar(String name, Integer position) {
Car car = new Car(name);
for (int i = 0; i < position; i++) {
car.tryToMove(5);
}
return car;
}
'우아한테크코스' 카테고리의 다른 글
SpringBoot Security 없이 Oauth2.0 로그인 Kakao편 (0) | 2021.07.05 |
---|---|
배포를 해보자 AWS, nginx, HTTPS 그리고 Spring #1 (2) | 2021.06.10 |
도커는 너무 어려워요 (1) | 2021.05.31 |
네트워크는 너무 어려워요 (2) | 2021.05.01 |
[우아한테크코스 3기] 레벨 1이 끝났다. (2) | 2021.04.10 |