#33 tdd(order-service): order - spring boot test

This commit is contained in:
haerong22
2023-02-12 11:23:00 +09:00
parent 6593b196c0
commit b67acc7ea9
9 changed files with 170 additions and 111 deletions

View File

@@ -0,0 +1,10 @@
package com.example.productorderservice.order;
import org.springframework.util.Assert;
record CreateOrderRequest(Long productId, int quantity) {
CreateOrderRequest {
Assert.notNull(productId, "상품 ID는 필수입니다.");
Assert.isTrue(quantity > 0, "수량은 0보다 커야 합니다.");
}
}

View File

@@ -0,0 +1,25 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.Product;
import org.springframework.util.Assert;
class Order {
private Long id;
private final Product product;
private final int quantity;
public Order(Product product, int quantity) {
Assert.notNull(product, "상품은 필수입니다.");
Assert.isTrue(quantity > 0, "수량은 0보다 커야 합니다.");
this.product = product;
this.quantity = quantity;
}
public void assignId(Long id) {
this.id = id;
}
public Long getId() {
return this.id;
}
}

View File

@@ -0,0 +1,27 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.Product;
import com.example.productorderservice.product.ProductRepository;
import org.springframework.stereotype.Component;
@Component
class OrderAdapter implements OrderPort {
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
public OrderAdapter(ProductRepository productRepository, OrderRepository orderRepository) {
this.productRepository = productRepository;
this.orderRepository = orderRepository;
}
@Override
public Product getProductById(Long productId) {
return productRepository.findById(productId)
.orElseThrow(() -> new IllegalArgumentException("상품이 존재하지 않습니다."));
}
@Override
public void save(Order order) {
orderRepository.save(order);
}
}

View File

@@ -0,0 +1,9 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.Product;
interface OrderPort {
Product getProductById(Long productId);
void save(Order order);
}

View File

@@ -0,0 +1,18 @@
package com.example.productorderservice.order;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
@Repository
class OrderRepository {
private final Map<Long, Order> persistence = new HashMap<>();
private Long sequence = 0L;
public void save(Order order) {
order.assignId(++sequence);
persistence.put(order.getId(), order);
}
}

View File

@@ -0,0 +1,21 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.Product;
import org.springframework.stereotype.Service;
@Service
class OrderService {
private final OrderPort orderPort;
OrderService(OrderPort orderPort) {
this.orderPort = orderPort;
}
public void createOrder(CreateOrderRequest request) {
Product product = orderPort.getProductById(request.productId());
Order order = new Order(product, request.quantity());
orderPort.save(order);
}
}

View File

@@ -4,7 +4,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
class ProductService {
public class ProductService {
private final ProductPort productPort;
ProductService(ProductPort productPort) {

View File

@@ -1,128 +1,32 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.DiscountPolicy;
import com.example.productorderservice.product.Product;
import com.example.productorderservice.product.ProductRepository;
import org.junit.jupiter.api.BeforeEach;
import com.example.productorderservice.product.ProductService;
import com.example.productorderservice.product.ProductSteps;
import org.junit.jupiter.api.Test;
import org.springframework.util.Assert;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class OrderServiceTest {
@Autowired
private OrderService orderService;
private OrderPort orderPort;
private OrderRepository orderRepository;
@BeforeEach
void setUp() {
orderRepository = new OrderRepository();
orderPort = new OrderPort() {
@Override
public Product getProductById(Long productId) {
return new Product("상품명", 1000, DiscountPolicy.NONE);
}
@Override
public void save(Order order) {
orderRepository.save(order);
}
};
orderService = new OrderService(orderPort);
}
@Autowired
private ProductService productService;
@Test
void 상품주문() {
final Long productId = 1L;
final int quantity = 2;
final CreateOrderRequest request = new CreateOrderRequest(productId, quantity);
productService.addProduct(ProductSteps.상품등록요청_생성());
final CreateOrderRequest request = 상품주문요청_생성();
orderService.createOrder(request);
}
private record CreateOrderRequest(Long productId, int quantity) {
private CreateOrderRequest(Long productId, int quantity) {
this.productId = productId;
this.quantity = quantity;
Assert.notNull(productId, "상품 ID는 필수입니다.");
Assert.isTrue(quantity > 0, "수량은 0보다 커야 합니다.");
}
}
private class OrderService {
private final OrderPort orderPort;
private OrderService(OrderPort orderPort) {
this.orderPort = orderPort;
}
public void createOrder(CreateOrderRequest request) {
Product product = orderPort.getProductById(request.productId());
Order order = new Order(product, request.quantity());
orderPort.save(order);
}
private static CreateOrderRequest 상품주문요청_생성() {
final Long productId = 1L;
final int quantity = 2;
return new CreateOrderRequest(productId, quantity);
}
private class OrderAdapter implements OrderPort {
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
public OrderAdapter(ProductRepository productRepository, OrderRepository orderRepository) {
this.productRepository = productRepository;
this.orderRepository = orderRepository;
}
@Override
public Product getProductById(Long productId) {
return productRepository.findById(productId)
.orElseThrow(() -> new IllegalArgumentException("상품이 존재하지 않습니다."));
}
@Override
public void save(Order order) {
orderRepository.save(order);
}
}
private class Order {
private Long id;
private final Product product;
private final int quantity;
public Order(Product product, int quantity) {
Assert.notNull(product, "상품은 필수입니다.");
Assert.isTrue(quantity > 0, "수량은 0보다 커야 합니다.");
this.product = product;
this.quantity = quantity;
}
public void assignId(Long id) {
this.id = id;
}
public Long getId() {
return this.id;
}
}
private class OrderRepository {
private final Map<Long, Order> persistence = new HashMap<>();
private Long sequence = 0L;
public void save(Order order) {
order.assignId(++sequence);
persistence.put(order.getId(), order);
}
}
private interface OrderPort {
Product getProductById(Long productId);
void save(Order order);
}
}

View File

@@ -0,0 +1,45 @@
package com.example.productorderservice.order;
import com.example.productorderservice.product.DiscountPolicy;
import com.example.productorderservice.product.Product;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class OrderServiceUnitTest {
private OrderService orderService;
private OrderPort orderPort;
private OrderRepository orderRepository;
@BeforeEach
void setUp() {
orderRepository = new OrderRepository();
orderPort = new OrderPort() {
@Override
public Product getProductById(Long productId) {
return new Product("상품명", 1000, DiscountPolicy.NONE);
}
@Override
public void save(Order order) {
orderRepository.save(order);
}
};
orderService = new OrderService(orderPort);
}
@Test
void 상품주문() {
final CreateOrderRequest request = 상품주문요청_생성();
orderService.createOrder(request);
}
private static CreateOrderRequest 상품주문요청_생성() {
final Long productId = 1L;
final int quantity = 2;
return new CreateOrderRequest(productId, quantity);
}
}