STS 4.0.1(스프링 부트)에서
TDD(테스트 주도 개발 Test Driven Development) 실습하기
들어가는 글. 대다수의 사람들은 다음 두 가지 단순한 법칙을 따름으로써 잠재력을 한껏 발휘할 수 있다. 1. 어떤 코드건 작성하기 전에 실패하는 자동화된 테스트를 작성하라. 2. 중복을 제거하라. | |
요구사항 및 개선사항 목록 - $5 + 10CHF = $10 (환율이 2:1일 경우) - - amount를 private로 만들기
- Money 반올림? -신규 : equals( ) 동질성 기능을 구현 <- 이번 예제의 목표 -신규 : hashCode( ) -신규 : Equal null -신규 : Equal object | 목적. 테스트 주도 개발의 리듬 이해 1. 재빨리 테스트를 하나 추가한다. 2. 모든 체스트를 실행하고 새로 추가한 것이 실패하는 지 확인한다 3. 코드를 조금 바꾼다. 4. 모든 테스트를 실행하고 전부 성공하는지 확인한다. 5. 리팩토링을 통해 중복을 제거한다. |
지난 장에 못다 남긴 글
느낌( 부작용에 대한 혐오감)을 테스트(하나의 Dollar 객체에 곱하기를 두번 수헹하는 것)로 변환하는 것은 TDD의 일반적인 주제이다.
3장. 모두를 위한 평등
3-0. 문제 인식
1) 저자의 경험 중 가장 형편없는 버그는 두번째 수표의 값을 변화시키는 바람에 첫번째 수표의 값까지 변하게 되는 문제이다. 별칭의 문제이다. 이를 개선하기 위해서는 값 객체를 사용해야한다. 값 객체의 제약 중 하나가 객체의 인스턴스 변수가 생성자를 통해 일단 설정된 후에는 결코 변하지 않기 때문에 값 객체를 사용하면 별칭에 걱정할 필요가 없다. ( 저자가 말하는 별칭은 변수 또는 메서드 이름을 말하는 것으로 생각된다. ) 2) 그런데 사실, 우리가 작성한 Dollar 객체같이 객체를 값처럼 쓸 수 있는 것을 값 객체 패턴 Value Object Pattern 이라고 한다. 값 객체(Value Object)는 개념적으로는 아주 작고 단순한 객체이다. 하지만 도메인 지향 디자인(Domain-Driven Design)과 객체지향 프로그래밍의 필수적인 요소이다. 값 객체는 두개의 값 객체의 동일성(equality) 은 Identity에 기반하지 않고 그들의 컨텐츠로 한다로 정의된다. (the equality of two Value Object is not based on identity) 동일성 에 대한 연산자가 두개 있다. '==' 와 '===' 이다. '=='는 equality 테스팅을 위한 것인데 스칼라(scalar)나 문자열 혹은 정수형에 값이 같은지를 체크하는 연산자이다. 반면에 '==='는 두 객체를 사용하고 있을때에 두 객체가 실제로 같은지에 대한 것을 판별해준다. 두 객체가 같다는 말은 같은 메모리 위치를 공유한다는 것이고 한쪽 객체에서 어떤 연산으로 객체의 값을 바꾸면 다른 객체에도 영향을 미친다는 뜻이다. 2) 요컨데, 이 장에서 얻고자 하는 목표는 동질성 기능을 구현하여 Dollar와 Dollar를 직접 비교하는 것이다. 이 과정에서 삼각측량전략을 사용한다. 삼각측량이란 만약 라디오 신호를 두 수신국에서 감지하고 있을 때, 수신국 사이의 거리가 알려져있고 각 수신국의 신호 방향을 알고 있다면 이 정보만으로 충분히 신호의 거리와 방위를 알 수 있다. |
3-1. 일단 테스트를 진행한다.
package com.noramlstory;
import static org.junit.Assert.assertEquals;
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 {
@Test
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product;
product = five.times(2);
assertEquals(10, product.amount);
product = five.times(3);
assertEquals(15, product.amount);
}
// 3장. 모두를 위한 평등
@Test
public void testEquality() {
// 3-1. 일단 테스트를 진행한다. $5 == $5 ( $5 같다 $5 )
assertTrue(new Dollar(5).equals(new Dollar(5)));
}
}
class Dollar{
int amount;
Dollar(int amount){
this.amount = amount;
}
Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
}
3-2 일단 가짜로 라도, 돌아가게 만든다.
package com.noramlstory;
import static org.junit.Assert.assertEquals;
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 {
@Test
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product;
product = five.times(2);
assertEquals(10, product.amount);
product = five.times(3);
assertEquals(15, product.amount);
}
// 3장. 모두를 위한 평등
@Test
public void testEquality() {
// 3-1. 일단 테스트를 진행한다.
assertTrue(new Dollar(5).equals(new Dollar(5)));
}
}
class Dollar{
int amount;
Dollar(int amount){
this.amount = amount;
}
Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
// 3-2 일단 가짜로 라도, 돌아가게 만든다.
public boolean equals(Object object) {
return true;
}
}
3-3 삼각 측량을 위해 반대? 비교를 하나 추가 해본다.
package com.noramlstory;
import static org.junit.Assert.assertEquals;
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 {
@Test
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product;
product = five.times(2);
assertEquals(10, product.amount);
product = five.times(3);
assertEquals(15, product.amount);
}
// 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{
int amount;
Dollar(int amount){
this.amount = amount;
}
Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
// 3-2 일단 가짜로 라도, 돌아가게 만든다.
public boolean equals(Object object) {
return true;
}
}
3-4 동치성을 일반화 한다. -> equals() 메소드를 통해 동질성 기능 구현
package com.noramlstory;
import static org.junit.Assert.assertEquals;
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 {
@Test
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product;
product = five.times(2);
assertEquals(10, product.amount);
product = five.times(3);
assertEquals(15, product.amount);
}
// 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{
int amount;
Dollar(int amount){
this.amount = amount;
}
Dollar times(int multiplier) {
return new Dollar(amount * multiplier);
}
// 3-2 일단 가짜로 돌아가게 만든다.
// public boolean equals(Object object) {
// return true;
// }
// 3-4 동치성을 일반화 한다
public boolean equals(Object object) {
Dollar dollar = (Dollar) object;
return amount == dollar.amount;
}
}
3-5 오늘 예제가 지난 예제와 달라진 점은? 또는 개인적인 해설
이전에는 기대 값과 Dollar(5)와 비교했다면
assertEquals(10 , product.amount);
오늘은 Dollar(5)와 Dollar(n)을 비교했다는 점이다.
assertTrue(new Dollar(5) .equals(new Dollar(5)));
동치라는 어려운? 단어가 나왔지만 결국 같은 곳에 사는가 == , 같은 존재인가 === 를 구분하기 위해 나온 용어이다.
전자는 변수라는 주소가 같은 곳에 담겨 있는 상태이고 후자는 주소과 값까지 같은 것을 말한다.
이를테면 동명인과 동일인 의 차이 정도?
라고 이해하면 좋을 것 같다.
여기서 잠깐~ ;D 스프링에서도 유사한 예제가 있어 링크를 걸어둡니다~ |
'새로워지기 > 서른의 생활코딩' 카테고리의 다른 글
스프링 부트에서 토비 3.1 따라하기 : 쉬어가는 그림 01 Architecture of Spring for MVC (0) | 2019.02.27 |
---|---|
스프링 부트에서 테스트 주도 개발 실습 - 4장. 프라이버시 (0) | 2019.02.23 |
스프링 부트에서 토비 3.1 따라하기 : 1장 - 1.5 스프링의 IoC (0) | 2019.02.22 |
스프링 부트에서 토비 3.1 따라하기 : 1장 - 1.4 제어의 역전 IoC (0) | 2019.02.21 |
스프링 부트에서 토비 3.1 따라하기 : 1장 - 1.3 DAO 확장 (0) | 2019.02.21 |
댓글