#33 tdd(order-service): payment - pojo

This commit is contained in:
haerong22
2023-02-14 01:41:56 +09:00
parent 7a7fbefb95
commit 71bb50f3e2
16 changed files with 263 additions and 2 deletions

View File

@@ -12,7 +12,7 @@ import javax.persistence.*;
@Table(name = "orders")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
class Order {
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -29,4 +29,7 @@ class Order {
this.quantity = quantity;
}
public int getTotalPrice() {
return product.getDiscountedPrice() * quantity;
}
}

View File

@@ -1,6 +1,19 @@
package com.example.productorderservice.product;
public enum DiscountPolicy {
NONE
NONE {
@Override
int applyDiscount(int price) {
return price;
}
},
FIX_1000_AMOUNT {
@Override
int applyDiscount(int price) {
return Math.max(price - 1000, 0);
}
}
;
abstract int applyDiscount(int price);
}

View File

@@ -38,4 +38,8 @@ class Product {
this.price = price;
this.discountPolicy = discountPolicy;
}
public int getDiscountedPrice() {
return discountPolicy.applyDiscount(price);
}
}

View File

@@ -0,0 +1,19 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.DiscountPolicy;
import com.example.productorderservice.product.Product;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class OrderTest {
@Test
void getTotalPrice() {
Order order = new Order(new Product("상품", 1000, DiscountPolicy.NONE), 2);
int totalPrice = order.getTotalPrice();
assertThat(totalPrice).isEqualTo(2000);
}
}

View File

@@ -0,0 +1,9 @@
package com.example.productorderservice.payment;
public class ConsolePaymentGateway implements PaymentGateway {
@Override
public void execute(int totalPrice, String cardNumber) {
System.out.println("결제 완료");
}
}

View File

@@ -0,0 +1,34 @@
package com.example.productorderservice.payment;
import com.example.productorderservice.order.Order;
import org.springframework.util.Assert;
class Payment {
private Long id;
private final Order order;
private final String cardNumber;
public Payment(Order order, String cardNumber) {
Assert.notNull(order, "주문은 필수입니다.");
Assert.hasText(cardNumber, "카드번호는 필수입니다.");
this.order = order;
this.cardNumber = cardNumber;
}
public void assign(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public int getPrice() {
return order.getTotalPrice();
}
public String getCardNumber() {
return cardNumber;
}
}

View File

@@ -0,0 +1,30 @@
package com.example.productorderservice.payment;
import com.example.productorderservice.order.Order;
import com.example.productorderservice.product.DiscountPolicy;
import com.example.productorderservice.product.Product;
class PaymentAdapter implements PaymentPort {
private final PaymentGateway paymentGateway;
private final PaymentRepository paymentRepository;
PaymentAdapter(PaymentGateway paymentGateway, PaymentRepository paymentRepository) {
this.paymentGateway = paymentGateway;
this.paymentRepository = paymentRepository;
}
@Override
public Order getOrder(Long orderId) {
return new Order(new Product("상품1", 1000, DiscountPolicy.NONE), 2);
}
@Override
public void pay(int totalPrice, String cardNumber) {
paymentGateway.execute(totalPrice, cardNumber);
}
@Override
public void save(Payment payment) {
paymentRepository.save(payment);
}
}

View File

@@ -0,0 +1,5 @@
package com.example.productorderservice.payment;
interface PaymentGateway {
void execute(int totalPrice, String cardNumber);
}

View File

@@ -0,0 +1,11 @@
package com.example.productorderservice.payment;
import com.example.productorderservice.order.Order;
interface PaymentPort {
Order getOrder(Long orderId);
void pay(int totalPrice, String cardNumber);
void save(Payment payment);
}

View File

@@ -0,0 +1,14 @@
package com.example.productorderservice.payment;
import java.util.HashMap;
import java.util.Map;
class PaymentRepository {
private final Map<Long, Payment> persistence = new HashMap<>();
private Long sequence = 0L;
public void save(Payment payment) {
payment.assign(++sequence);
persistence.put(payment.getId(), payment);
}
}

View File

@@ -0,0 +1,11 @@
package com.example.productorderservice.payment;
import org.springframework.util.Assert;
record PaymentRequest(Long orderId, String cardNumber) {
PaymentRequest {
Assert.notNull(orderId, "주문 ID는 필수입니다.");
Assert.hasText(cardNumber, "카드번호는 필수입니다.");
}
}

View File

@@ -0,0 +1,20 @@
package com.example.productorderservice.payment;
import com.example.productorderservice.order.Order;
class PaymentService {
private final PaymentPort paymentPort;
PaymentService(PaymentPort paymentPort) {
this.paymentPort = paymentPort;
}
public void payment(PaymentRequest request) {
final Order order = paymentPort.getOrder(request.orderId());
final Payment payment = new Payment(order, request.cardNumber());
paymentPort.pay(payment.getPrice(), payment.getCardNumber());
paymentPort.save(payment);
}
}

View File

@@ -0,0 +1,27 @@
package com.example.productorderservice.payment;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class PaymentServiceTest {
private PaymentService paymentService;
private PaymentPort paymentPort;
@BeforeEach
void setUp() {
final PaymentGateway paymentGateway = new ConsolePaymentGateway();
final PaymentRepository paymentRepository= new PaymentRepository();
paymentPort = new PaymentAdapter(paymentGateway, paymentRepository);
paymentService = new PaymentService(paymentPort);
}
@Test
void 상품주문() {
final PaymentRequest request = PaymentSteps.주문결제요청_생성();
paymentService.payment(request);
}
}

View File

@@ -0,0 +1,10 @@
package com.example.productorderservice.payment;
public class PaymentSteps {
public static PaymentRequest 주문결제요청_생성() {
final Long orderId = 1L;
final String cardNumber = "1234-1234-1234-1234";
return new PaymentRequest(orderId, cardNumber);
}
}

View File

@@ -0,0 +1,33 @@
package com.example.productorderservice.product;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class DiscountPolicyTest {
@Test
void applyDiscount_NONE() {
final int price = 1000;
final int discountedPrice = DiscountPolicy.NONE.applyDiscount(price);
assertThat(discountedPrice).isEqualTo(price);
}
@Test
void applyDiscount_FIX_1000_AMOUNT() {
final int price = 2000;
final int discountedPrice = DiscountPolicy.FIX_1000_AMOUNT.applyDiscount(price);
assertThat(discountedPrice).isEqualTo(1000);
}
@Test
void applyDiscount_FIX_1000_AMOUNT_over() {
final int price = 500;
final int discountedPrice = DiscountPolicy.FIX_1000_AMOUNT.applyDiscount(price);
assertThat(discountedPrice).isEqualTo(0);
}
}

View File

@@ -16,4 +16,22 @@ class ProductTest {
assertThat(product.getPrice()).isEqualTo(2000);
}
@Test
void none_discounted_product() {
Product product = new Product("상품명", 1000, DiscountPolicy.NONE);
int discountedPrice = product.getDiscountedPrice();
assertThat(discountedPrice).isEqualTo(1000);
}
@Test
void fix_1000_discounted_product() {
Product product = new Product("상품명", 2000, DiscountPolicy.FIX_1000_AMOUNT);
int discountedPrice = product.getDiscountedPrice();
assertThat(discountedPrice).isEqualTo(1000);
}
}