STS 4.0.1(스프링 부트)에서
TDD(테스트 주도 개발 Test Driven Development) 실습하기
들어가는 글. 대다수의 사람들은 다음 두 가지 단순한 법칙을 따름으로써 잠재력을 한껏 발휘할 수 있다. 1. 어떤 코드건 작성하기 전에 실패하는 자동화된 테스트를 작성하라. 2. 중복을 제거하라. | |
요구사항 및 개선사항 목록 - $5 + 10CHF = $10 (환율이 2:1일 경우) - - amount를 private로 만들기 <- 이번 예제의 목표
- Money 반올림?
- hashCode( ) - Equal null - Equal object | 목적. 테스트 주도 개발의 리듬 이해 1. 재빨리 테스트를 하나 추가한다. 2. 모든 체스트를 실행하고 새로 추가한 것이 실패하는 지 확인한다 3. 코드를 조금 바꾼다. 4. 모든 테스트를 실행하고 전부 성공하는지 확인한다. 5. 리팩토링을 통해 중복을 제거한다. |
4장. 프라이버시
4-1. PREVIOUS 프리비어스
다음은 그동안 작성해온 Dollar.class이다.
class Dollar{
int amount;
Dollar(int amount){
this.amount = amount;
}
Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
// 3-4 동치성을 일반화 한다
public boolean equals(Object object) {
Dollar dollar = (Dollar) object;
return amount == dollar.amount;
}
}
이 클래스는 amount라고 하는 변수를 담아 자신을 그 값을 반환하는 생성자, times(), equals()라는 메소드 들을 가지고 있다.
3장에서는 equals() 메소드를 통해 동치성을 해결했고 이번 장에서는 times()를 통해 호출받은 객체의 값에 인자로 수만큼 곱한 값을 갖는 Dollar를 반환하도록 할 예정이다. 현재까지는 테스트 코드가 정확히 그것을 말하지는 못하고 있다. 라고 저자는 말한다.
무슨 소리인가 했다. 다 읽어보니 결과는 다르지 않지만 엄밀히 말하면 다르다. 그리고 그 안에 이번 장에서 이루고자 하는 결과가 담겨 있다.
이전 테스트코드를 보면 "times()를 통해 호출받은 객체의 값에 인자로 받은 수 만큼 곱한 값을 갖는 Dollar를 반환하도록 할 예정이다." 의 과정 중에 product라는 Dollar 오브젝트를 거쳐서 코드가 진행되고 있음을 알 수 있다. 다시말해 위 과정을 수행하는데 위에 밑줄을 두개의 Dollar 오브젝트가 사용되고 있는 것이다.
이것을 하나로 줄여보자.
그러면 Dollar 클래스의 인스턴스 변수 amount 를 사용하는 코드는 Dollar 자신밖에 없게 된다.
여기서 한번 더 궁금증을 갖을 수 있는 부분.. five 도 있고 product 도 있는데 왜 자기 자신이라고 하지? 제 소견으로는 five는 new연산자를 통해 자기 자신을 반환하고 있는 오브젝트이고. product는 그저 Dollar 타입의 변수 에 불과하기 때문이다.
여하튼, 인스턴스 변수 amount 를 사용하는 코드는 Dollar 자신밖에 없기 때문에 amount를 private로 조정할 수 있다.
자기 자신만 쓸 수 있는 값으로.
4-2. 코드에 반영
1) assertion 단을 동치성을 반영한 코드로 작성
2) Dollar products; 및 관련 코드를 소거하고 동치성 코드에 인라인 형태로 병합
package com.noramlstory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestTdd2019 {
// 4장. 프라이버시
@Test
public void testMultiplication() {
Dollar five = new Dollar(5);
//assertEquals(10, product.amount);
assertEquals(new Dollar(10), five.times(2)); // assertion 수정 : 동치성을 반영, product 변수 제거
assertEquals(new Dollar(15), five.times(3)); // assertion 수정 : 동치성을 반영, product 변수 제거
}
// 3장. 모두를 위한 평등
@Test
public void testEquality() {
// 3-1. 일단 테스트를 진행한다. $5 == $5 ( $5 같다 $5 )
assertTrue(new Dollar(5).equals(new Dollar(5)));
// 3-3. 삼각 측량을 위해 거짓 비교?를 하나 추가 해본다. $5 != $6 ( $5 같지않다 $6 )
assertFalse(new Dollar(5).equals(new Dollar(6)));
}
}
class Dollar{
private int amount;
Dollar(int amount){
this.amount = amount;
}
Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
// 3-4 동치성을 일반화 한다
public boolean equals(Object object) {
Dollar dollar = (Dollar) object;
return amount == dollar.amount;
}
}
4-3. 결과
4-4. 지금까지의 실습 내용 검토
1) 오직 테스트를 향상시키기 위해서만 개발된 기능을 사용
2) 두 테스트가 동시에 실패하면 망한다
만약 동치성 테스트가 동치성에 대한 코드가 정확히 작동한다는 것을 검증하는데 실패한다면, 곱하기 테스트 역시 곱하기에 대한 코드가 정확하게 작동한다는 것을 검증하는데 실패하게 된다 고 쓰여있다. 한번 더 번역하면
이전에 작성한 곱하기 테스트 코드를 동치성 코드 방식으로 수정했으니 동치성 코드가 틀리면 이전에 했던 곱하기 코드도 맞는지 안맞는지 알 길이 없어지지 않겠느냐 는 말로 들린다.
3) 위험 요소가 있음에도 계속 진행
4) 테스트와 코드 사이의 결합도를 낮추기 위해, 테스트하는 객체의 새기능을 사용
'새로워지기 > 서른의 생활코딩' 카테고리의 다른 글
스프링 부트에서 토비 3.1 따라하기 : 쉬어가는 그림 02 springMaven 구조도(작성중) (0) | 2019.02.27 |
---|---|
스프링 부트에서 토비 3.1 따라하기 : 쉬어가는 그림 01 Architecture of Spring for MVC (0) | 2019.02.27 |
스프링 부트에서 테스트 주도 개발 실습 - 3장. 모두를 위한 평등 (0) | 2019.02.23 |
스프링 부트에서 토비 3.1 따라하기 : 1장 - 1.5 스프링의 IoC (0) | 2019.02.22 |
스프링 부트에서 토비 3.1 따라하기 : 1장 - 1.4 제어의 역전 IoC (0) | 2019.02.21 |
댓글