티스토리 뷰
오늘은 10,11,12 장 내용을 다루어 보자!
10장. 흥미로운 발급
책에서는 또 비유적으로 시간이라는 은유를 썻는데 나는 있는 그대로(?) 작성 하였다.
카드번호, 유효기간, 결제 금액 값 필요 equals() hashCode() 계좌 수수료 (30%) 공용 newIssuance newIssuance 신규 발급 추가 사용가능 국가 |
공용 newIssuance 로 중복 코드를 줄이자.
Payment newIssuance(double chargeRate) {
if (getClass().equals(Card.class)) {
return Payment.card(chargeRate);
} else if (getClass().equals(Account.class)){
return Payment.account(chargeRate);
} else {
return null;
}
}
위 처럼 코드를 수정하고 테스트를 돌리면 승리의 초록색 막대가 나온다~! 오늘도 하나의 업적을 만들고 퇴근!
11장 모든 악의 근원
카드번호, 유효기간, 결제 금액 값 필요 equals() hashCode() 계좌 수수료 (30%) newIssuance 신규 발급 추가 사용가능 국가 |
Paymt 에 두 하위 클래스에는 이제 생성자 밖에 없다.
package com.example.demo;
public class Card extends Payment{
Card(double chargeRate, String country) {
super(chargeRate, country);
}
}
package com.example.demo;
public class Account extends Payment{
Account(double chargeRate, String country) {
super(chargeRate, country);
}
}
생성자만 있는 하위 클레스는 필요가 없기 때문에, 삭제하도록 하자 삭제 가능하게 Payment 에 하위 클래스에 대한 참조를 상위 클래스에 대한 참조로 변경하자.
static Payment card(double chargeRate) {
return new Payment(chargeRate, "Korea");
}
static Payment account(double chargeRate) {
return new Payment(chargeRate, "USA");
}
이제 테스트 코드에서 Card, Account 에 대한 의존성을 지울 수 있다. 다음 으로 동치성 테스트가 충분히 되었는지 확인해 보자.
@Test
void equalsTest() {
assertTrue(Payment.card(0.2).equals(Payment.card(0.2)));
assertFalse(Payment.card(0.2).equals(Payment.card(0.3)));
assertTrue(Payment.account(0.2).equals(Payment.account(0.2)));
assertFalse(Payment.account(0.2).equals(Payment.account(0.3)));
assertFalse(Payment.account(0.3).equals(Payment.card(0.3)));
}
너무 과하게 테스트를 하고 있다. 첫번째, 두번째 assert 를 같은 의미 이므로 삭제하자.
@Test
void equalsTest() {
assertTrue(Payment.account(0.2).equals(Payment.account(0.2)));
assertFalse(Payment.account(0.2).equals(Payment.account(0.3)));
assertFalse(Payment.account(0.3).equals(Payment.card(0.3)));
}
1. 이번장에서는, 하위 클래스의 속을 들어내는 것을 완료 하고, 하위 클래스를 삭제하였다.
2. 기존 소스 구조에서는 필요 했지만 새로운 구조에서는 필요 없게 된 테스트를 제거 했다.
12장. 드디어, 복합 결제
요구 사항 항목이 너무 많다. 이쯤에서 한번 요구사항을 정리하고 진행하자.
카드 수수료(0.2) + 계좌 수수료(0.3) = 결제 금액 (복합결제가 가능 50대 50 으로만 결제 가능) |
전체 복합결제 스토리를 한번에 다룰지 모르겠다.
카드 수수료(0.2) + 계좌 수수료(0.3) = 결제 금액 (복합결제가 가능 50대 50 으로만 결제 가능) 카드 수수료(0.2) + 카드 수수료(0.3) |
우선 같은 결제 수단에 대한 복합결제에서 시작해 보자.
복합결제에 대하여 테스트 코드를 만들고
@Test
public void testSimplePaymentAddition() {
Payment add = Payment.card(0.2).add(Payment.card(0.3));
assertEquals(Payment.card(0.25), add);
}
Payment.card(0.25) 를 반환하는 식으로 가짜 구현 할 수도 있지만, 구현해야 할 상황이 명확 하므로 명확하게 구현한다.
public Payment add(Payment addPayment) {
return new Payment((this.chargeRate + addPayment.chargeRate) / 2, this.country);
}
여기서 우리는 Card, Account 의 복합결제를 나타는데 이를 나타내는 Payment 객체를 만들 것이다.
이를 이해 하기 위해, 메타포를 아래와 같이 생각해 보도록 하겠다.
(Card 수수료 + 게좌 수수료) / 2 와 같은 수식어다.
여기서 연산의 결과로 Expression 들이 생기는데, 그중 하나는 합이 될 것이다.
결제수수료를 이용해서 Expression 은 대표 결제 수단으로 축약할 수 있다.
이 메타포를 테스트에 적용해 보자.
@Test
public void testSimplePaymentAddition() {
...
assertEquals(Payment.card(0.25), reduced);
}
reduced(축약된)란 이름의 Expression은 Expression에 대표 결제수단을 적용함으로서 얻어진다.
실세계에서 수수료가 적용되는 곳은 어디인가. 온라인 쇼핑몰 이라고 가정하자.
@Test
public void testSimplePaymentAddition() {
...
Payment reduced = onlineShoppingMall.reduce(representativePayment, "korea");
assertEquals(Payment.card(0.25), reduced);
}
OnlineShoppingMall 객체를 만들고
@Test
public void testSimplePaymentAddition() {
...
OnlineShoppingMall onlineShoppingMall = new OnlineShoppingMall();
Payment reduced = onlineShoppingMall.reduce(representativePayment, "korea");
assertEquals(Payment.card(0.25), reduced);
}
두 결제수단에서 대표결제수단을 구하는건 Expression 이다.
@Test
public void testSimplePaymentAddition() {
...
Expression representativePayment = card.add(card);
OnlineShoppingMall onlineShoppingMall = new OnlineShoppingMall();
Payment reduced = onlineShoppingMall.reduce(representativePayment, "korea");
assertEquals(Payment.card(0.25), reduced);
}
card 를 만든다.
@Test
public void testSimplePaymentAddition() {
...
Payment card = Payment.card(0.25);
Expression representativePayment = card.add(card);
OnlineShoppingMall onlineShoppingMall = new OnlineShoppingMall();
Payment reduced = onlineShoppingMall.reduce(representativePayment, "Korea");
assertEquals(Payment.card(0.25), reduced);
}
이제 컴파일 하려면 Expression 인터페이스가 필요하다. (class 도 좋지만 interface 가 더 가볍다.)
그리고 초록 막대가 나오도록 쭉 구현 하겠다.
초록 막대가 보인다.
이제 다음 장에서 리팩토링할 준비가 되었다. 다음장에서 부터 리팩토링을 진행 하겠다.
이 장에서 우리는
1. 메타포들을 신중히 생각해 보았다.
2. 새 메타포에 기반하여 기존의 테스트를 재작성 하였다.
3. 큰 테스트를 작은 테스트로 줄여서 발전을 할 수 있도록 했다.
참고 : 테스트주도 개발 (켄트백)
'테스트' 카테고리의 다른 글
테스트 주도 개발 - TDD 마스터 하기 (0) | 2023.03.19 |
---|---|
테스트 주도 개발_6 (0) | 2023.02.18 |
테스트 주도 개발_4 (0) | 2023.02.12 |
테스트 주도개발_3 (0) | 2023.02.12 |
테스트 주도개발_2 (0) | 2023.02.11 |
- Total
- Today
- Yesterday
- 웹개발
- GateWayApi
- Python #FastAPI
- 테스트 주도 개발
- 켄트 백
- TDD
- fastapi
- 퀜트백
- Python
- 테스트주도개발
- kafka
- 웹서비스
- data mining
- AWS
- 테스트
- nodejs
- data crawling
- SpringBoot
- MSA
- MQ
- 분산처리
- mongodb
- EC2
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |