TDD 클린코드 with Java 16 기 2주차 회고

Patrick YOO·2023년 4월 15일

TDD

목록 보기
3/8
post-thumbnail

Good Point

  • 엘래강트 오브젝트를 완독 하였다
  • 앨래강트 오브젝트에 명시 되어있는 룰을 지켜가며 코딩을 하였으며 클린코딩에 대해 좀더 가까워지고 있는것 같다 엘레강트 오브젝트
  • 과제를 위한 시간이 충분히 확보되고 있다.

Bad Point

  • 클린 코드에 대한 룰을 지키며 코딩을 하는것이 어려우며 무조건 룰을 지키는것이 클린코드인것인지 아직 감이 잘 오고 있지 않다.

What I Learned And What were reviewed

    @CsvSource(value = {"4:1", "5:1", "6:1", "7:1", "8:1", "9:1"}, delimiter = ':')
    void carMoveForwardTest(int valueSource, int expectedDistance) {
        Car car = new Car(TEST_CAR_NAME);
        assertThat(car.getDistance()).isEqualTo(0);
        car.moveForwardByNumber(valueSource);
        assertThat(car.getDistance()).isEqualTo(expectedDistance);
    }

    @ParameterizedTest(name = "[{index}] randomNumber 가 {0} 일 경우 차량은 한턴 정지한다")
    @CsvSource(value = {"0:0","1:0","2:0","3:0"}, delimiter = ':')
    void carStopTest(int valueSource, int expectedDistance) {
        Car car = new Car(TEST_CAR_NAME);
        assertThat(car.getDistance()).isEqualTo(0);
        car.moveForwardByNumber(valueSource);
        assertThat(car.getDistance()).isEqualTo(expectedDistance);
    }

위와같은 코드에서 테스트 케이스가 너무 장황하며 실제로 상태가 변경되는 그 경계값에 대한 테스트만 이뤄지도록 수정을 아래와 같이 권장한다

    @CsvSource(value = {"4:1"}, delimiter = ':')
    void carMoveForwardTest(int valueSource, int expectedDistance) {
        Car car = new Car(TEST_CAR_NAME);
        assertThat(car.getDistance()).isEqualTo(0);
        car.moveForwardByNumber(valueSource);
        assertThat(car.getDistance()).isEqualTo(expectedDistance);
    }

    @ParameterizedTest(name = "[{index}] randomNumber 가 {0} 일 경우 차량은 한턴 정지한다")
    @CsvSource(value = {"3:0"}, delimiter = ':')
    void carStopTest(int valueSource, int expectedDistance) {
        Car car = new Car(TEST_CAR_NAME);
        assertThat(car.getDistance()).isEqualTo(0);
        car.moveForwardByNumber(valueSource);
        assertThat(car.getDistance()).isEqualTo(expectedDistance);
    }

아래와 같은 static 상수 를 사용할 경우 해당 코드를 의존하는 코드는 테스트하기가 매우 어려워진다.

public class RandomNumber {
	
    public static int randomNumber() {
    	return ...
    }
}

public class Car {
	void move() {
    	if(randomNumber() > 3) }
        	...
        }
    }
}

이와같은 코드가 작성되어있을 경우 테스트 하기 어려워지기때문에 public static 함수를 없앤후 interface로 선언하여 wrapping 해 준다면 해당 코드는 테스트 가능한 코드로 전환이 가능하다.

public interface MoveStrategy {
	int randomNumber();
}

public class RandomNumber implements MoveStrategy{
	
    public int randomNumber(); {
    	return ...
    }
}

public class Car {
	void move(MoveStrategy s) {
    	if(s.randomNumber > 3) }
        	...
        }
    }
}

public class FakeClass implements MoveStrategy {
	... 테스트용 fake 객체
}

단위테스트는 누락되는 로직없이 꼼꼼히 수행하자.


public class Distance {
	private final int distance;
}

public class Car {
	private Distance distance;
    ...
    
    public Distance getDistance() {
    	return this.distance
    }
}

위와같은 원시값을 래핑하는 클래스를 직접 사용하는 클래스 에서는 불변성을 유지 하지 않았을때 코드 간결성이
높아지고 값에대한 수정이 이뤄지는것이 아니라면 Getter 를 사용해도 좋다.

하지만 원시값에 대한 불변성은 반드시 유지를 시키자.

profile
자유인을 꿈꾸는 개발자

0개의 댓글