#33 tdd(order-service): payment - pojo
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -38,4 +38,8 @@ class Product {
|
||||
this.price = price;
|
||||
this.discountPolicy = discountPolicy;
|
||||
}
|
||||
|
||||
public int getDiscountedPrice() {
|
||||
return discountPolicy.applyDiscount(price);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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("결제 완료");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.productorderservice.payment;
|
||||
|
||||
interface PaymentGateway {
|
||||
void execute(int totalPrice, String cardNumber);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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, "카드번호는 필수입니다.");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user