diff --git a/build.gradle b/build.gradle index d8d7bf6..91366eb 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,7 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation 'org.assertj:assertj-core:3.6.1' } tasks.named('test') { diff --git a/src/main/java/yourssu/order/domain/Order.java b/src/main/java/yourssu/order/domain/Order.java index 2846d14..d1804ee 100644 --- a/src/main/java/yourssu/order/domain/Order.java +++ b/src/main/java/yourssu/order/domain/Order.java @@ -8,4 +8,8 @@ public class Order { public Order(List items) { this.items = items; } + + public List getItems() { + return items; + } } diff --git a/src/main/java/yourssu/order/domain/OrderItem.java b/src/main/java/yourssu/order/domain/OrderItem.java index e2bd709..bc587fc 100644 --- a/src/main/java/yourssu/order/domain/OrderItem.java +++ b/src/main/java/yourssu/order/domain/OrderItem.java @@ -10,4 +10,17 @@ public OrderItem(String name, int price, int count) { this.price = price; this.count = count; } + + + public int getPrice() { + return price; + } + + public int getCount() { + return count; + } + + public String getName() { + return name; + } } diff --git a/src/main/java/yourssu/order/domain/OrderUser.java b/src/main/java/yourssu/order/domain/OrderUser.java new file mode 100644 index 0000000..087a43f --- /dev/null +++ b/src/main/java/yourssu/order/domain/OrderUser.java @@ -0,0 +1,15 @@ +package yourssu.order.domain; + +import java.util.List; + +public class OrderUser { + private final List orders; + + public OrderUser(List orders) { + this.orders = orders; + } + + public List getOrders() { + return orders; + } +} diff --git a/src/main/java/yourssu/order/service/OrderAnalyticsService.java b/src/main/java/yourssu/order/service/OrderAnalyticsService.java index 9566f39..466564a 100644 --- a/src/main/java/yourssu/order/service/OrderAnalyticsService.java +++ b/src/main/java/yourssu/order/service/OrderAnalyticsService.java @@ -1,4 +1,17 @@ package yourssu.order.service; +import yourssu.order.domain.OrderUser; + +import java.util.List; +import java.util.stream.Collectors; + public class OrderAnalyticsService { + public static double getAverageOrderAmount(List user) { + return user.stream() + .flatMap(orderUser -> orderUser.getOrders().stream()) + .flatMap(order -> order.getItems().stream()) + .collect(Collectors.averagingDouble( + orderItem -> orderItem.getCount() * orderItem.getPrice() + )); + } } diff --git a/src/main/java/yourssu/user/domain/User.java b/src/main/java/yourssu/user/domain/User.java index ffbb384..ced4d90 100644 --- a/src/main/java/yourssu/user/domain/User.java +++ b/src/main/java/yourssu/user/domain/User.java @@ -1,6 +1,8 @@ package yourssu.user.domain; import java.util.List; + +import yourssu.order.domain.Order; import yourssu.post.domain.Post; public class User { diff --git a/src/test/java/yourssu/JavaPlaygroundApplicationTests.java b/src/test/java/yourssu/JavaPlaygroundApplicationTests.java index b793052..18c906d 100644 --- a/src/test/java/yourssu/JavaPlaygroundApplicationTests.java +++ b/src/test/java/yourssu/JavaPlaygroundApplicationTests.java @@ -2,10 +2,63 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import yourssu.order.domain.Order; +import yourssu.order.domain.OrderItem; +import yourssu.order.domain.OrderUser; +import yourssu.order.service.OrderAnalyticsService; +import yourssu.user.domain.User; + +import java.util.Arrays; +import java.util.List; +import java.util.OptionalDouble; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Java6Assertions.offset; @SpringBootTest class JavaPlaygroundApplicationTests { + + private List prepareData() { + OrderItem item1 = new OrderItem("item1", 2000, 2); // 4000 + OrderItem item2 = new OrderItem("item2", 500, 3); // 1500 + Order order1 = new Order(Arrays.asList(item1, item2)); + + OrderItem item3 = new OrderItem("item3", 1000, 1); // 1000 + OrderItem item4 = new OrderItem("item4", 300, 5); // 1500 + Order order2 = new Order(Arrays.asList(item3, item4)); + + return Arrays.asList(new OrderUser(List.of(order1)), new OrderUser(List.of(order2))); + } + @Test - void contextLoads() { + void 모든_주문상품의_개별_총금액을_계산하고_하나의_리스트로_펼친다() { + List orderUsers = prepareData(); + + List expectedItemTotals = List.of(4000, 1500, 1000, 1500); + + assertThat(expectedItemTotals) + .as("총 4개의 주문 상품 금액이 계산되어야 함") + .hasSize(4); + + assertThat(expectedItemTotals) + .as("각 주문 상품의 (price * count) 결과는 [4000, 1500, 1000, 1500] 순으로 일치해야 함") + .containsExactlyElementsOf(expectedItemTotals); + + assertThat(expectedItemTotals.stream().mapToInt(Integer::intValue).sum()) + .as("계산된 모든 금액의 합은 8000이어야 함") + .isEqualTo(8000); + } + + @Test + void 모든_주문상품의_최종_평균_금액을_정확히_계산_한다() { + List orderUsers = prepareData(); + double expectedAverage = 2000.0; + + double averagePrice = OrderAnalyticsService.getAverageOrderAmount(orderUsers); + + assertThat(averagePrice) + .as("모든 주문 상품의 평균 금액은 %.2f 이어야 함", expectedAverage) + .isEqualTo(expectedAverage, offset(0.001)); // 0.001 오차 범위 허용 + } }