From 24ee5a26ae07ad6870113d01b74b813c0f82f981 Mon Sep 17 00:00:00 2001 From: hand Date: Fri, 26 Aug 2022 22:28:17 +0900 Subject: [PATCH 01/21] =?UTF-8?q?feat(kitchenpos):=20readme=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 67 +++++++++++++------------------------------------------ 1 file changed, 15 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 6698f662a..85648a9ee 100644 --- a/README.md +++ b/README.md @@ -14,21 +14,22 @@ docker compose -p kitchenpos up -d ### 메뉴 그룹 - [ ] 메뉴 그룹은 N개의 메뉴를 가질 수 있다. +- [ ] 메뉴그룹 이름은 null일 수 없다. - [ ] 메뉴그룹 이름은 비어있을 수 없다. ### 메뉴 - 생성 -- [ ] 메뉴 가격은 비어있을 수 없다. +- [ ] 메뉴 가격은 null일 수 없다. - [ ] 메뉴 가격은 음수일 수 없다. - [ ] 메뉴는 특정 메뉴 그룹에 항상 속해야 한다. - [ ] 메뉴는 N 개의 메뉴 상품을 가진다. - [ ] 메뉴에 속한 상품은 모두 존재해야 한다. - [ ] 메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다. -- [ ] 메뉴 이름은 비어있을 수 없다. +- [ ] 메뉴 이름은 null일 수 없다. - [ ] 메뉴 이름에는 욕설이 포함될 수 없다. - 가격 변경 -- [ ] 가격은 비어있거나 음수일 수 없다. +- [ ] 가격은 null이거나 음수일 수 없다. - [ ] 가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다. - [ ] 변경하고자 하는 가격이 현재 가격과 같아선 안된다. @@ -46,39 +47,29 @@ docker compose -p kitchenpos up -d ### 상품 생성 -- [ ] 상품의 가격은 비어있거나 음수여서는 안된다. -- [ ] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다. +- [ ] 상품의 가격은 null이거나 음수여서는 안된다. +- [ ] 상품의 이름은 null이거나 욕설이 포함돼서는 안된다. 가격 변경 -- [ ] 가격은 비어있거나 0보다 작아서는 안된다. +- [ ] 가격은 null이거나 0보다 작아서는 안된다. - [ ] 상품은 존재해야 한다. - [ ] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.) - [ ] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다. -### 주문메뉴정보 -- 주문메뉴정보는 주문에 포함된 각 메뉴의 수량을 관리한다. -- [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). +### OrderLineItem +- OrderLineItem은 주문에 포함된 각 메뉴의 수량을 관리한다. +- [ ] OrderLineItem 의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). - [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다. - [ ] 홀이 아닐경우, 음수를 허용하지 않는다. - [ ] 모든 메뉴는 전시중이어야 한다. -- [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. +- [ ] 메뉴 가격과 OrderLineItem에 명시된 가격은 동일해야 한다. ### 주문 생성 -``` -주문의 상태 변화 -WAITING -``` - [ ] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN) -- [ ] 타입은 비어있을 수 없다. -- [ ] 주문은 여러 주문메뉴정보를 가질 수 있다. -- [ ] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다. -- [ ] 주문에 포함된 주문메뉴정보는, 주문메뉴정보의 제약조건을 모두 만족해야 한다. - - [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). - - [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다. - - [ ] 홀이 아닐경우, 음수를 허용하지 않는다. - - [ ] 모든 메뉴는 전시중이어야 한다. - - [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. +- [ ] 타입은 null일 수 없다. +- [ ] 주문은 여러 orderLineItem 을 가질 수 있다. +- [ ] 주문은 적어도 하나의 orderLineItem을 가져야 한다. - [ ] 주문의 초기 상태는 WAITING이다. - [ ] 주문의 타입이 DEVIVERY라면, 주소를 필수로 입력받는다. - [ ] 주소는 널이거나 비어있지 않다. @@ -87,56 +78,28 @@ WAITING - [ ] 주문 테이블은 존재해야 한다. 주문 accept -``` -주문의 상태 변화 -WAITING -> ACCEPTED -``` - [ ] 주문은 존재해야 한다. - [ ] 주문의 상태는 WAITING 상태여야 한다. - [ ] 주문 타입이 DELIVER라면, 라이더 시스템으로 배달 요청을 전송한다. - [ ] 주문 상태를 ACCEPTED 로 변경된다.. 주문 serve -``` -주문의 상태 변화 -ACCEPTED -> SERVED -``` - [ ] 주문은 존재해야 한다. - [ ] 주문 상태가 ACCEPTED 상태여야 한다. - [ ] 주문 상태는 SERVED 로 변경된다. 주문 startDelivery -``` -사전 조건 -DELIVERY 타입. - -주문의 상태 변화 -SERVED -> DELIVERING -``` - [ ] 주문은 존재해야 한다. - [ ] 주문은 DELIVERY 타입이어야 한다. - [ ] 주문은 SERVED 상태여야 한다. - [ ] 주문 상태는 DELIVERING 으로 변경된다. 주문 completeDelivery -``` -주문의 상태 변화 -DELIVERING -> DELIVERED -``` - [ ] 주문은 존재해야 한다. - [ ] 주문 상태는 DELIVERING 이어야 한다. - [ ] 주문 상태는 DELIVERED 로 변경된다. 주문 complete -``` -주문의 상태 변화 - -[DELIVERY 타입] -DELIVERED -> COMPLETED - -[TAKEOUT, EAT_INT 타입] -SERVED -> COMPLETED -``` - [ ] 주문은 존재해야 한다. - [ ] 주문이 DELIVERY 타입이면, DELIVERED 상태여야 한다. - [ ] 주문이 TAKEOUT, EAT_IN 타입이면, SERVED 상태여야 한다. @@ -145,7 +108,7 @@ SERVED -> COMPLETED ## 주문 테이블 생성 -- [ ] 테이블 이름은 비어있을 수 없다. +- [ ] 테이블 이름은 null이거나 비어서는 안된다. 주문 테이블 sit - [ ] 주문 테이블은 존재해야 한다. From 9a843ceb963f9dd0e706fe249836b77668c41cdb Mon Sep 17 00:00:00 2001 From: hand Date: Sat, 27 Aug 2022 23:00:16 +0900 Subject: [PATCH 02/21] =?UTF-8?q?refactor(kitchenpos):=20order=20line=20it?= =?UTF-8?q?em=20->=20=EC=A3=BC=EB=AC=B8=EB=A9=94=EB=89=B4=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A1=9C=20=EB=B3=80=EA=B2=BD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 85648a9ee..a2226211a 100644 --- a/README.md +++ b/README.md @@ -14,22 +14,21 @@ docker compose -p kitchenpos up -d ### 메뉴 그룹 - [ ] 메뉴 그룹은 N개의 메뉴를 가질 수 있다. -- [ ] 메뉴그룹 이름은 null일 수 없다. - [ ] 메뉴그룹 이름은 비어있을 수 없다. ### 메뉴 - 생성 -- [ ] 메뉴 가격은 null일 수 없다. +- [ ] 메뉴 가격은 비어있을 수 없다. - [ ] 메뉴 가격은 음수일 수 없다. - [ ] 메뉴는 특정 메뉴 그룹에 항상 속해야 한다. - [ ] 메뉴는 N 개의 메뉴 상품을 가진다. - [ ] 메뉴에 속한 상품은 모두 존재해야 한다. - [ ] 메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다. -- [ ] 메뉴 이름은 null일 수 없다. +- [ ] 메뉴 이름은 비어있을 수 없다. - [ ] 메뉴 이름에는 욕설이 포함될 수 없다. - 가격 변경 -- [ ] 가격은 null이거나 음수일 수 없다. +- [ ] 가격은 비어있거나 음수일 수 없다. - [ ] 가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다. - [ ] 변경하고자 하는 가격이 현재 가격과 같아선 안된다. @@ -47,29 +46,29 @@ docker compose -p kitchenpos up -d ### 상품 생성 -- [ ] 상품의 가격은 null이거나 음수여서는 안된다. -- [ ] 상품의 이름은 null이거나 욕설이 포함돼서는 안된다. +- [ ] 상품의 가격은 비어있거나 음수여서는 안된다. +- [ ] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다. 가격 변경 -- [ ] 가격은 null이거나 0보다 작아서는 안된다. +- [ ] 가격은 비어있거나 0보다 작아서는 안된다. - [ ] 상품은 존재해야 한다. - [ ] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.) - [ ] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다. -### OrderLineItem -- OrderLineItem은 주문에 포함된 각 메뉴의 수량을 관리한다. -- [ ] OrderLineItem 의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). +### 주문메뉴정보 +- 주문메뉴정보는 주문에 포함된 각 메뉴의 수량을 관리한다. +- [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). - [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다. - [ ] 홀이 아닐경우, 음수를 허용하지 않는다. - [ ] 모든 메뉴는 전시중이어야 한다. -- [ ] 메뉴 가격과 OrderLineItem에 명시된 가격은 동일해야 한다. +- [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. ### 주문 생성 - [ ] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN) -- [ ] 타입은 null일 수 없다. -- [ ] 주문은 여러 orderLineItem 을 가질 수 있다. -- [ ] 주문은 적어도 하나의 orderLineItem을 가져야 한다. +- [ ] 타입은 비어있을 수 없다. +- [ ] 주문은 여러 주문메뉴정보 을 가질 수 있다. +- [ ] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다. - [ ] 주문의 초기 상태는 WAITING이다. - [ ] 주문의 타입이 DEVIVERY라면, 주소를 필수로 입력받는다. - [ ] 주소는 널이거나 비어있지 않다. @@ -108,7 +107,7 @@ docker compose -p kitchenpos up -d ## 주문 테이블 생성 -- [ ] 테이블 이름은 null이거나 비어서는 안된다. +- [ ] 테이블 이름은 비어있을 수 없다. 주문 테이블 sit - [ ] 주문 테이블은 존재해야 한다. From ae8d002afb6f0f37504cf2deb2f12a46a8b01663 Mon Sep 17 00:00:00 2001 From: hand Date: Sat, 27 Aug 2022 23:28:39 +0900 Subject: [PATCH 03/21] =?UTF-8?q?refactor(kitchenpos):=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EC=9D=98=20=EC=83=81=ED=83=9C=20=EB=B3=80=ED=99=94=20?= =?UTF-8?q?=ED=91=9C=ED=98=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a2226211a..6698f662a 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,20 @@ docker compose -p kitchenpos up -d ### 주문 생성 +``` +주문의 상태 변화 +WAITING +``` - [ ] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN) - [ ] 타입은 비어있을 수 없다. -- [ ] 주문은 여러 주문메뉴정보 을 가질 수 있다. +- [ ] 주문은 여러 주문메뉴정보를 가질 수 있다. - [ ] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다. +- [ ] 주문에 포함된 주문메뉴정보는, 주문메뉴정보의 제약조건을 모두 만족해야 한다. + - [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). + - [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다. + - [ ] 홀이 아닐경우, 음수를 허용하지 않는다. + - [ ] 모든 메뉴는 전시중이어야 한다. + - [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. - [ ] 주문의 초기 상태는 WAITING이다. - [ ] 주문의 타입이 DEVIVERY라면, 주소를 필수로 입력받는다. - [ ] 주소는 널이거나 비어있지 않다. @@ -77,28 +87,56 @@ docker compose -p kitchenpos up -d - [ ] 주문 테이블은 존재해야 한다. 주문 accept +``` +주문의 상태 변화 +WAITING -> ACCEPTED +``` - [ ] 주문은 존재해야 한다. - [ ] 주문의 상태는 WAITING 상태여야 한다. - [ ] 주문 타입이 DELIVER라면, 라이더 시스템으로 배달 요청을 전송한다. - [ ] 주문 상태를 ACCEPTED 로 변경된다.. 주문 serve +``` +주문의 상태 변화 +ACCEPTED -> SERVED +``` - [ ] 주문은 존재해야 한다. - [ ] 주문 상태가 ACCEPTED 상태여야 한다. - [ ] 주문 상태는 SERVED 로 변경된다. 주문 startDelivery +``` +사전 조건 +DELIVERY 타입. + +주문의 상태 변화 +SERVED -> DELIVERING +``` - [ ] 주문은 존재해야 한다. - [ ] 주문은 DELIVERY 타입이어야 한다. - [ ] 주문은 SERVED 상태여야 한다. - [ ] 주문 상태는 DELIVERING 으로 변경된다. 주문 completeDelivery +``` +주문의 상태 변화 +DELIVERING -> DELIVERED +``` - [ ] 주문은 존재해야 한다. - [ ] 주문 상태는 DELIVERING 이어야 한다. - [ ] 주문 상태는 DELIVERED 로 변경된다. 주문 complete +``` +주문의 상태 변화 + +[DELIVERY 타입] +DELIVERED -> COMPLETED + +[TAKEOUT, EAT_INT 타입] +SERVED -> COMPLETED +``` - [ ] 주문은 존재해야 한다. - [ ] 주문이 DELIVERY 타입이면, DELIVERED 상태여야 한다. - [ ] 주문이 TAKEOUT, EAT_IN 타입이면, SERVED 상태여야 한다. From 06cf9280bec3982d600fc72571b9b763b06111a3 Mon Sep 17 00:00:00 2001 From: hand Date: Fri, 2 Sep 2022 20:08:41 +0900 Subject: [PATCH 04/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20=EB=BC=88?= =?UTF-8?q?=EB=8C=80=20=EC=83=9D=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/kitchenpos/util/Operation.java | 6 +++ src/test/java/kitchenpos/util/TestGlue.java | 39 ++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/test/java/kitchenpos/util/Operation.java create mode 100644 src/test/java/kitchenpos/util/TestGlue.java diff --git a/src/test/java/kitchenpos/util/Operation.java b/src/test/java/kitchenpos/util/Operation.java new file mode 100644 index 000000000..bb222908f --- /dev/null +++ b/src/test/java/kitchenpos/util/Operation.java @@ -0,0 +1,6 @@ +package kitchenpos.util; + +public interface Operation { + + void run(); +} diff --git a/src/test/java/kitchenpos/util/TestGlue.java b/src/test/java/kitchenpos/util/TestGlue.java new file mode 100644 index 000000000..915f6d117 --- /dev/null +++ b/src/test/java/kitchenpos/util/TestGlue.java @@ -0,0 +1,39 @@ +package kitchenpos.util; + +import java.util.ArrayList; +import java.util.List; + +public class TestGlue { + + private final List operations; + + public TestGlue() { + this(new ArrayList<>()); + } + + public TestGlue(List operations) { + this.operations = operations; + } + + public void run() { + this.operations.forEach(Operation::run); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private List operations; + + public Builder then(Operation op) { + this.operations.add(op); + return this; + } + + public TestGlue build() { + return new TestGlue(operations); + } + } +} From 23a96124d3418f5c6ffced0d6f166c5918442bc4 Mon Sep 17 00:00:00 2001 From: hand Date: Sat, 3 Sep 2022 01:14:54 +0900 Subject: [PATCH 05/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20context=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EB=B0=8F=20=EC=8B=A4=ED=96=89=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kitchenpos/util/EnableTestGlue.java | 16 +++ .../kitchenpos/util/OperationDescription.java | 10 ++ .../util/TestGlueConfiguration.java | 15 +++ .../kitchenpos/util/TestGlueInitializer.java | 65 +++++++++ .../kitchenpos/util/TestGlueOperation.java | 15 +++ .../util/TestGlueOperationContext.java | 31 +++++ .../utiltest/TestGlueInitializerTest.java | 125 ++++++++++++++++++ 7 files changed, 277 insertions(+) create mode 100644 src/test/java/kitchenpos/util/EnableTestGlue.java create mode 100644 src/test/java/kitchenpos/util/OperationDescription.java create mode 100644 src/test/java/kitchenpos/util/TestGlueConfiguration.java create mode 100644 src/test/java/kitchenpos/util/TestGlueInitializer.java create mode 100644 src/test/java/kitchenpos/util/TestGlueOperation.java create mode 100644 src/test/java/kitchenpos/util/TestGlueOperationContext.java create mode 100644 src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java diff --git a/src/test/java/kitchenpos/util/EnableTestGlue.java b/src/test/java/kitchenpos/util/EnableTestGlue.java new file mode 100644 index 000000000..d86b6c9db --- /dev/null +++ b/src/test/java/kitchenpos/util/EnableTestGlue.java @@ -0,0 +1,16 @@ +package kitchenpos.util; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.context.annotation.Import; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Import(TestGlueConfiguration.class) +@Documented +public @interface EnableTestGlue { + +} diff --git a/src/test/java/kitchenpos/util/OperationDescription.java b/src/test/java/kitchenpos/util/OperationDescription.java new file mode 100644 index 000000000..0ec70f622 --- /dev/null +++ b/src/test/java/kitchenpos/util/OperationDescription.java @@ -0,0 +1,10 @@ +package kitchenpos.util; + +public class OperationDescription { + + private final String description; + + public OperationDescription(String description) { + this.description = description; + } +} diff --git a/src/test/java/kitchenpos/util/TestGlueConfiguration.java b/src/test/java/kitchenpos/util/TestGlueConfiguration.java new file mode 100644 index 000000000..d9f1fe7c5 --- /dev/null +++ b/src/test/java/kitchenpos/util/TestGlueConfiguration.java @@ -0,0 +1,15 @@ +package kitchenpos.util; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.stereotype.Component; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Component +@Documented +public @interface TestGlueConfiguration { +} diff --git a/src/test/java/kitchenpos/util/TestGlueInitializer.java b/src/test/java/kitchenpos/util/TestGlueInitializer.java new file mode 100644 index 000000000..5938b93f7 --- /dev/null +++ b/src/test/java/kitchenpos/util/TestGlueInitializer.java @@ -0,0 +1,65 @@ +package kitchenpos.util; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.web.bind.annotation.GetMapping; + +public class TestGlueInitializer implements ApplicationContextAware { + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + var context = (AnnotationConfigApplicationContext) applicationContext; + context.registerBean(TestGlueOperationContext.class); + + var testGlueOperationContext = context.getBean(TestGlueOperationContext.class); + + var testGlueConfigurationNames = context.getBeanNamesForAnnotation(TestGlueConfiguration.class); + + for (String testGlueConfigurationName : testGlueConfigurationNames) { + Object bean = context.getBean(testGlueConfigurationName); + setTestGlueOperation(bean, testGlueOperationContext); + } + } + + @GetMapping("test") + private void setTestGlueOperation(Object bean, TestGlueOperationContext testGlueOperationContext) { + Method[] methods = bean.getClass().getMethods(); + for (Method method : methods) { + if (!method.isAnnotationPresent(TestGlueOperation.class)) { + continue; + } + + validateParameterCount(method); + + TestGlueOperation testGlueOperation = method.getAnnotation(TestGlueOperation.class); + String description = testGlueOperation.value(); + + validateDescription(method, description); + + testGlueOperationContext.put(description, () -> { + try { + method.invoke(bean); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + }); + } + } + + private void validateDescription(Method method, String description) { + if (description.isBlank()) { + throw new IllegalArgumentException(String.format("Method (%s) description cannot be empty", method.getName())); + } + } + + private void validateParameterCount(Method method) { + int parameterCount = method.getParameterCount(); + if (parameterCount != 0) { + throw new IllegalArgumentException(String.format("Method (%s) cannot have parameter.", method.getName())); + } + } +} diff --git a/src/test/java/kitchenpos/util/TestGlueOperation.java b/src/test/java/kitchenpos/util/TestGlueOperation.java new file mode 100644 index 000000000..88e3ba011 --- /dev/null +++ b/src/test/java/kitchenpos/util/TestGlueOperation.java @@ -0,0 +1,15 @@ +package kitchenpos.util; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface TestGlueOperation { + + String value() default ""; +} diff --git a/src/test/java/kitchenpos/util/TestGlueOperationContext.java b/src/test/java/kitchenpos/util/TestGlueOperationContext.java new file mode 100644 index 000000000..2545e5e94 --- /dev/null +++ b/src/test/java/kitchenpos/util/TestGlueOperationContext.java @@ -0,0 +1,31 @@ +package kitchenpos.util; + +import java.util.HashMap; +import java.util.Map; + +public class TestGlueOperationContext { + + private final Map volume; + + public TestGlueOperationContext() { + this(new HashMap<>()); + } + + public TestGlueOperationContext(Map volume) { + this.volume = volume; + } + + public void put(String description, Operation operation) { + volume.put(description, operation); + } + + public Operation get(String description) { + Operation operation = volume.get(description); + + if (operation == null) { + throw new IllegalArgumentException("can not found operation"); + } + + return operation; + } +} diff --git a/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java b/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java new file mode 100644 index 000000000..76046e56b --- /dev/null +++ b/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java @@ -0,0 +1,125 @@ +package kitchenpos.utiltest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +import kitchenpos.util.Operation; +import kitchenpos.util.TestGlueConfiguration; +import kitchenpos.util.TestGlueInitializer; +import kitchenpos.util.TestGlueOperation; +import kitchenpos.util.TestGlueOperationContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +class TestGlueInitializerTest { + + private AnnotationConfigApplicationContext context; + private TestGlueOperationContext testGlueOperationContext; + private TestConfiguration1 testConfiguration1; + private TestConfiguration2 testConfiguration2; + private TestConfiguration3 testConfiguration3; + + @BeforeEach + void setUp() { + context = mock(AnnotationConfigApplicationContext.class); + testGlueOperationContext = new TestGlueOperationContext(); + testConfiguration1 = new TestConfiguration1(); + testConfiguration2 = new TestConfiguration2(); + testConfiguration3 = new TestConfiguration3(); + + given(context.getBean(TestGlueOperationContext.class)).willReturn(testGlueOperationContext); + given(context.getBeanNamesForAnnotation(TestGlueConfiguration.class)).willReturn(new String[]{"a", "b", "c"}); + given(context.getBean("a")).willReturn(testConfiguration1); + given(context.getBean("b")).willReturn(testConfiguration2); + given(context.getBean("c")).willReturn(testConfiguration3); + } + + @DisplayName("testGlue 초기화 시 operationContext에 Operation이 등록 되는지 확인한다.") + @Test + void testGlueInitialize() { + // given + var testGlueInitializer = new TestGlueInitializer(); + + // when + testGlueInitializer.setApplicationContext(context); + + Operation test1 = testGlueOperationContext.get("test1"); + Operation test2 = testGlueOperationContext.get("test2"); + Operation test3 = testGlueOperationContext.get("test3"); + test1.run(); + test2.run(); + test3.run(); + + // then + assertAll( + () -> assertThat(testConfiguration1.getA()).isOne(), + () -> assertThat(testConfiguration2.getA()).isOne(), + () -> assertThat(testConfiguration3.getA()).isOne() + ); + } + + @DisplayName("파싱한 메서드가 실행되는지 확인한다.") + @Test + void testGlueMethodRun() { + var testGlueInitializer = new TestGlueInitializer(); + + // when + testGlueInitializer.setApplicationContext(context); + + // then + assertAll( + () -> assertThat(testGlueOperationContext.get("test1")).isNotNull(), + () -> assertThat(testGlueOperationContext.get("test2")).isNotNull(), + () -> assertThat(testGlueOperationContext.get("test3")).isNotNull() + ); + } + + @TestGlueConfiguration + public static class TestConfiguration1 { + + private int a = 0; + + @TestGlueOperation("test1") + public void test() { + a++; + } + + public int getA() { + return a; + } + } + + @TestGlueConfiguration + public static class TestConfiguration2 { + + private int a; + + @TestGlueOperation("test2") + public void test() { + a++; + } + + public int getA() { + return a; + } + } + + @TestGlueConfiguration + public static class TestConfiguration3 { + + private int a; + + @TestGlueOperation("test3") + public void test() { + a++; + } + + public int getA() { + return a; + } + } +} From 13921353d0eb52bdd04ecc6cead58064b5c5bd47 Mon Sep 17 00:00:00 2001 From: hand Date: Sat, 3 Sep 2022 01:33:58 +0900 Subject: [PATCH 06/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20runner=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/kitchenpos/util/EnableTestGlue.java | 2 +- src/test/java/kitchenpos/util/TestGlue.java | 40 +++++++++------- .../kitchenpos/util/TestGlueInitializer.java | 6 ++- .../java/kitchenpos/util/TestGlueRunner.java | 20 ++++++++ .../utiltest/TestConfiguration1.java | 19 ++++++++ .../utiltest/TestConfiguration2.java | 19 ++++++++ .../utiltest/TestConfiguration3.java | 19 ++++++++ .../utiltest/TestGlueInitializerTest.java | 46 ------------------- .../kitchenpos/utiltest/TestGlueTest.java | 44 ++++++++++++++++++ 9 files changed, 150 insertions(+), 65 deletions(-) create mode 100644 src/test/java/kitchenpos/util/TestGlueRunner.java create mode 100644 src/test/java/kitchenpos/utiltest/TestConfiguration1.java create mode 100644 src/test/java/kitchenpos/utiltest/TestConfiguration2.java create mode 100644 src/test/java/kitchenpos/utiltest/TestConfiguration3.java create mode 100644 src/test/java/kitchenpos/utiltest/TestGlueTest.java diff --git a/src/test/java/kitchenpos/util/EnableTestGlue.java b/src/test/java/kitchenpos/util/EnableTestGlue.java index d86b6c9db..7fa2f89f7 100644 --- a/src/test/java/kitchenpos/util/EnableTestGlue.java +++ b/src/test/java/kitchenpos/util/EnableTestGlue.java @@ -9,7 +9,7 @@ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) -@Import(TestGlueConfiguration.class) +@Import(TestGlueInitializer.class) @Documented public @interface EnableTestGlue { diff --git a/src/test/java/kitchenpos/util/TestGlue.java b/src/test/java/kitchenpos/util/TestGlue.java index 915f6d117..ec76382dc 100644 --- a/src/test/java/kitchenpos/util/TestGlue.java +++ b/src/test/java/kitchenpos/util/TestGlue.java @@ -5,35 +5,43 @@ public class TestGlue { - private final List operations; + private final TestGlueOperationContext context; - public TestGlue() { - this(new ArrayList<>()); + public TestGlue(TestGlueOperationContext context) { + this.context = context; } - public TestGlue(List operations) { - this.operations = operations; + public Builder builder() { + return new Builder(context, new ArrayList<>()); } - public void run() { - this.operations.forEach(Operation::run); - } + public static class Builder { - public static Builder builder() { - return new Builder(); - } + private final TestGlueOperationContext context; + private final List operations; - public static class Builder { + public Builder(TestGlueOperationContext context, List operations) { + this.context = context; + this.operations = operations; + } + + public Builder given(String op) { + this.operations.add(op); + return this; + } - private List operations; + public Builder when(String op) { + this.operations.add(op); + return this; + } - public Builder then(Operation op) { + public Builder then(String op) { this.operations.add(op); return this; } - public TestGlue build() { - return new TestGlue(operations); + public void assertStart() { + new TestGlueRunner(context, operations).assertStart(); } } } diff --git a/src/test/java/kitchenpos/util/TestGlueInitializer.java b/src/test/java/kitchenpos/util/TestGlueInitializer.java index 5938b93f7..29e03d918 100644 --- a/src/test/java/kitchenpos/util/TestGlueInitializer.java +++ b/src/test/java/kitchenpos/util/TestGlueInitializer.java @@ -5,15 +5,17 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.web.bind.annotation.GetMapping; public class TestGlueInitializer implements ApplicationContextAware { @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - var context = (AnnotationConfigApplicationContext) applicationContext; + var context = (GenericApplicationContext) applicationContext; + context.registerBean(TestGlueOperationContext.class); + context.registerBean(TestGlue.class); var testGlueOperationContext = context.getBean(TestGlueOperationContext.class); diff --git a/src/test/java/kitchenpos/util/TestGlueRunner.java b/src/test/java/kitchenpos/util/TestGlueRunner.java new file mode 100644 index 000000000..5458b4b13 --- /dev/null +++ b/src/test/java/kitchenpos/util/TestGlueRunner.java @@ -0,0 +1,20 @@ +package kitchenpos.util; + +import java.util.List; + +public class TestGlueRunner { + + private final TestGlueOperationContext testGlueOperationContext; + private final List operations; + + public TestGlueRunner(TestGlueOperationContext testGlueOperationContext, List operations) { + this.testGlueOperationContext = testGlueOperationContext; + this.operations = operations; + } + + public void assertStart() { + operations.stream() + .map(testGlueOperationContext::get) + .forEach(Operation::run); + } +} diff --git a/src/test/java/kitchenpos/utiltest/TestConfiguration1.java b/src/test/java/kitchenpos/utiltest/TestConfiguration1.java new file mode 100644 index 000000000..9330cebeb --- /dev/null +++ b/src/test/java/kitchenpos/utiltest/TestConfiguration1.java @@ -0,0 +1,19 @@ +package kitchenpos.utiltest; + +import kitchenpos.util.TestGlueConfiguration; +import kitchenpos.util.TestGlueOperation; + +@TestGlueConfiguration +public class TestConfiguration1 { + + private int a = 0; + + @TestGlueOperation("test1") + public void test() { + a++; + } + + public int getA() { + return a; + } +} diff --git a/src/test/java/kitchenpos/utiltest/TestConfiguration2.java b/src/test/java/kitchenpos/utiltest/TestConfiguration2.java new file mode 100644 index 000000000..40a118597 --- /dev/null +++ b/src/test/java/kitchenpos/utiltest/TestConfiguration2.java @@ -0,0 +1,19 @@ +package kitchenpos.utiltest; + +import kitchenpos.util.TestGlueConfiguration; +import kitchenpos.util.TestGlueOperation; + +@TestGlueConfiguration +public class TestConfiguration2 { + + private int a = 0; + + @TestGlueOperation("test2") + public void test() { + a++; + } + + public int getA() { + return a; + } +} diff --git a/src/test/java/kitchenpos/utiltest/TestConfiguration3.java b/src/test/java/kitchenpos/utiltest/TestConfiguration3.java new file mode 100644 index 000000000..d0d828dcd --- /dev/null +++ b/src/test/java/kitchenpos/utiltest/TestConfiguration3.java @@ -0,0 +1,19 @@ +package kitchenpos.utiltest; + +import kitchenpos.util.TestGlueConfiguration; +import kitchenpos.util.TestGlueOperation; + +@TestGlueConfiguration +public class TestConfiguration3 { + + private int a = 0; + + @TestGlueOperation("test3") + public void test() { + a++; + } + + public int getA() { + return a; + } +} diff --git a/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java b/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java index 76046e56b..749170bcd 100644 --- a/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java +++ b/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java @@ -8,7 +8,6 @@ import kitchenpos.util.Operation; import kitchenpos.util.TestGlueConfiguration; import kitchenpos.util.TestGlueInitializer; -import kitchenpos.util.TestGlueOperation; import kitchenpos.util.TestGlueOperationContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -77,49 +76,4 @@ void testGlueMethodRun() { () -> assertThat(testGlueOperationContext.get("test3")).isNotNull() ); } - - @TestGlueConfiguration - public static class TestConfiguration1 { - - private int a = 0; - - @TestGlueOperation("test1") - public void test() { - a++; - } - - public int getA() { - return a; - } - } - - @TestGlueConfiguration - public static class TestConfiguration2 { - - private int a; - - @TestGlueOperation("test2") - public void test() { - a++; - } - - public int getA() { - return a; - } - } - - @TestGlueConfiguration - public static class TestConfiguration3 { - - private int a; - - @TestGlueOperation("test3") - public void test() { - a++; - } - - public int getA() { - return a; - } - } } diff --git a/src/test/java/kitchenpos/utiltest/TestGlueTest.java b/src/test/java/kitchenpos/utiltest/TestGlueTest.java new file mode 100644 index 000000000..eafba743d --- /dev/null +++ b/src/test/java/kitchenpos/utiltest/TestGlueTest.java @@ -0,0 +1,44 @@ +package kitchenpos.utiltest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import kitchenpos.util.EnableTestGlue; +import kitchenpos.util.TestGlue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@EnableTestGlue +@SpringBootTest(classes = {TestConfiguration1.class, TestConfiguration2.class, TestConfiguration3.class}) +class TestGlueTest { + + @Autowired + private TestGlue testGlue; + + @Autowired + private TestConfiguration1 testConfiguration1; + + @Autowired + private TestConfiguration2 testConfiguration2; + + @Autowired + private TestConfiguration3 testConfiguration3; + + @DisplayName("testGlue를 이용하여 build가 제대로 이루어 지는지 확인한다.") + @Test + void build() { + testGlue.builder() + .given("test1") + .when("test2") + .then("test3") + .assertStart(); + + assertAll( + () -> assertThat(testConfiguration1.getA()).isOne(), + () -> assertThat(testConfiguration2.getA()).isOne(), + () -> assertThat(testConfiguration3.getA()).isOne() + ); + } +} From d15f3e9fad57c409b3e5471eb440a3d967a5e08c Mon Sep 17 00:00:00 2001 From: hand Date: Sat, 3 Sep 2022 12:18:49 +0900 Subject: [PATCH 07/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kitchenpos/util/{ => testglue}/EnableTestGlue.java | 2 +- .../java/kitchenpos/util/{ => testglue}/Operation.java | 2 +- .../util/{ => testglue}/OperationDescription.java | 2 +- .../java/kitchenpos/util/{ => testglue}/TestGlue.java | 2 +- .../util/{ => testglue}/TestGlueConfiguration.java | 2 +- .../util/{ => testglue}/TestGlueInitializer.java | 2 +- .../util/{ => testglue}/TestGlueOperation.java | 2 +- .../util/{ => testglue}/TestGlueOperationContext.java | 2 +- .../kitchenpos/util/{ => testglue}/TestGlueRunner.java | 2 +- .../testglue/test}/TestConfiguration1.java | 6 +++--- .../testglue/test}/TestConfiguration2.java | 6 +++--- .../testglue/test}/TestConfiguration3.java | 6 +++--- .../testglue/test}/TestGlueInitializerTest.java | 10 +++++----- .../{utiltest => util/testglue/test}/TestGlueTest.java | 6 +++--- 14 files changed, 26 insertions(+), 26 deletions(-) rename src/test/java/kitchenpos/util/{ => testglue}/EnableTestGlue.java (92%) rename src/test/java/kitchenpos/util/{ => testglue}/Operation.java (57%) rename src/test/java/kitchenpos/util/{ => testglue}/OperationDescription.java (82%) rename src/test/java/kitchenpos/util/{ => testglue}/TestGlue.java (96%) rename src/test/java/kitchenpos/util/{ => testglue}/TestGlueConfiguration.java (91%) rename src/test/java/kitchenpos/util/{ => testglue}/TestGlueInitializer.java (98%) rename src/test/java/kitchenpos/util/{ => testglue}/TestGlueOperation.java (91%) rename src/test/java/kitchenpos/util/{ => testglue}/TestGlueOperationContext.java (94%) rename src/test/java/kitchenpos/util/{ => testglue}/TestGlueRunner.java (93%) rename src/test/java/kitchenpos/{utiltest => util/testglue/test}/TestConfiguration1.java (55%) rename src/test/java/kitchenpos/{utiltest => util/testglue/test}/TestConfiguration2.java (55%) rename src/test/java/kitchenpos/{utiltest => util/testglue/test}/TestConfiguration3.java (55%) rename src/test/java/kitchenpos/{utiltest => util/testglue/test}/TestGlueInitializerTest.java (91%) rename src/test/java/kitchenpos/{utiltest => util/testglue/test}/TestGlueTest.java (89%) diff --git a/src/test/java/kitchenpos/util/EnableTestGlue.java b/src/test/java/kitchenpos/util/testglue/EnableTestGlue.java similarity index 92% rename from src/test/java/kitchenpos/util/EnableTestGlue.java rename to src/test/java/kitchenpos/util/testglue/EnableTestGlue.java index 7fa2f89f7..cfb23f148 100644 --- a/src/test/java/kitchenpos/util/EnableTestGlue.java +++ b/src/test/java/kitchenpos/util/testglue/EnableTestGlue.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/src/test/java/kitchenpos/util/Operation.java b/src/test/java/kitchenpos/util/testglue/Operation.java similarity index 57% rename from src/test/java/kitchenpos/util/Operation.java rename to src/test/java/kitchenpos/util/testglue/Operation.java index bb222908f..8b26a7f22 100644 --- a/src/test/java/kitchenpos/util/Operation.java +++ b/src/test/java/kitchenpos/util/testglue/Operation.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; public interface Operation { diff --git a/src/test/java/kitchenpos/util/OperationDescription.java b/src/test/java/kitchenpos/util/testglue/OperationDescription.java similarity index 82% rename from src/test/java/kitchenpos/util/OperationDescription.java rename to src/test/java/kitchenpos/util/testglue/OperationDescription.java index 0ec70f622..daefa7dee 100644 --- a/src/test/java/kitchenpos/util/OperationDescription.java +++ b/src/test/java/kitchenpos/util/testglue/OperationDescription.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; public class OperationDescription { diff --git a/src/test/java/kitchenpos/util/TestGlue.java b/src/test/java/kitchenpos/util/testglue/TestGlue.java similarity index 96% rename from src/test/java/kitchenpos/util/TestGlue.java rename to src/test/java/kitchenpos/util/testglue/TestGlue.java index ec76382dc..073c928dd 100644 --- a/src/test/java/kitchenpos/util/TestGlue.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlue.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/kitchenpos/util/TestGlueConfiguration.java b/src/test/java/kitchenpos/util/testglue/TestGlueConfiguration.java similarity index 91% rename from src/test/java/kitchenpos/util/TestGlueConfiguration.java rename to src/test/java/kitchenpos/util/testglue/TestGlueConfiguration.java index d9f1fe7c5..2a4a44d19 100644 --- a/src/test/java/kitchenpos/util/TestGlueConfiguration.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueConfiguration.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/src/test/java/kitchenpos/util/TestGlueInitializer.java b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java similarity index 98% rename from src/test/java/kitchenpos/util/TestGlueInitializer.java rename to src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java index 29e03d918..1a5afb172 100644 --- a/src/test/java/kitchenpos/util/TestGlueInitializer.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/src/test/java/kitchenpos/util/TestGlueOperation.java b/src/test/java/kitchenpos/util/testglue/TestGlueOperation.java similarity index 91% rename from src/test/java/kitchenpos/util/TestGlueOperation.java rename to src/test/java/kitchenpos/util/testglue/TestGlueOperation.java index 88e3ba011..587c829e0 100644 --- a/src/test/java/kitchenpos/util/TestGlueOperation.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueOperation.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/src/test/java/kitchenpos/util/TestGlueOperationContext.java b/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java similarity index 94% rename from src/test/java/kitchenpos/util/TestGlueOperationContext.java rename to src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java index 2545e5e94..ab87ee695 100644 --- a/src/test/java/kitchenpos/util/TestGlueOperationContext.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.util.HashMap; import java.util.Map; diff --git a/src/test/java/kitchenpos/util/TestGlueRunner.java b/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java similarity index 93% rename from src/test/java/kitchenpos/util/TestGlueRunner.java rename to src/test/java/kitchenpos/util/testglue/TestGlueRunner.java index 5458b4b13..f1dc90cae 100644 --- a/src/test/java/kitchenpos/util/TestGlueRunner.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java @@ -1,4 +1,4 @@ -package kitchenpos.util; +package kitchenpos.util.testglue; import java.util.List; diff --git a/src/test/java/kitchenpos/utiltest/TestConfiguration1.java b/src/test/java/kitchenpos/util/testglue/test/TestConfiguration1.java similarity index 55% rename from src/test/java/kitchenpos/utiltest/TestConfiguration1.java rename to src/test/java/kitchenpos/util/testglue/test/TestConfiguration1.java index 9330cebeb..32c479cd8 100644 --- a/src/test/java/kitchenpos/utiltest/TestConfiguration1.java +++ b/src/test/java/kitchenpos/util/testglue/test/TestConfiguration1.java @@ -1,7 +1,7 @@ -package kitchenpos.utiltest; +package kitchenpos.util.testglue.test; -import kitchenpos.util.TestGlueConfiguration; -import kitchenpos.util.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; @TestGlueConfiguration public class TestConfiguration1 { diff --git a/src/test/java/kitchenpos/utiltest/TestConfiguration2.java b/src/test/java/kitchenpos/util/testglue/test/TestConfiguration2.java similarity index 55% rename from src/test/java/kitchenpos/utiltest/TestConfiguration2.java rename to src/test/java/kitchenpos/util/testglue/test/TestConfiguration2.java index 40a118597..6de4499d6 100644 --- a/src/test/java/kitchenpos/utiltest/TestConfiguration2.java +++ b/src/test/java/kitchenpos/util/testglue/test/TestConfiguration2.java @@ -1,7 +1,7 @@ -package kitchenpos.utiltest; +package kitchenpos.util.testglue.test; -import kitchenpos.util.TestGlueConfiguration; -import kitchenpos.util.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; @TestGlueConfiguration public class TestConfiguration2 { diff --git a/src/test/java/kitchenpos/utiltest/TestConfiguration3.java b/src/test/java/kitchenpos/util/testglue/test/TestConfiguration3.java similarity index 55% rename from src/test/java/kitchenpos/utiltest/TestConfiguration3.java rename to src/test/java/kitchenpos/util/testglue/test/TestConfiguration3.java index d0d828dcd..1d2974640 100644 --- a/src/test/java/kitchenpos/utiltest/TestConfiguration3.java +++ b/src/test/java/kitchenpos/util/testglue/test/TestConfiguration3.java @@ -1,7 +1,7 @@ -package kitchenpos.utiltest; +package kitchenpos.util.testglue.test; -import kitchenpos.util.TestGlueConfiguration; -import kitchenpos.util.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; @TestGlueConfiguration public class TestConfiguration3 { diff --git a/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java b/src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java similarity index 91% rename from src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java rename to src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java index 749170bcd..758b9573c 100644 --- a/src/test/java/kitchenpos/utiltest/TestGlueInitializerTest.java +++ b/src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java @@ -1,14 +1,14 @@ -package kitchenpos.utiltest; +package kitchenpos.util.testglue.test; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import kitchenpos.util.Operation; -import kitchenpos.util.TestGlueConfiguration; -import kitchenpos.util.TestGlueInitializer; -import kitchenpos.util.TestGlueOperationContext; +import kitchenpos.util.testglue.Operation; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueInitializer; +import kitchenpos.util.testglue.TestGlueOperationContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/kitchenpos/utiltest/TestGlueTest.java b/src/test/java/kitchenpos/util/testglue/test/TestGlueTest.java similarity index 89% rename from src/test/java/kitchenpos/utiltest/TestGlueTest.java rename to src/test/java/kitchenpos/util/testglue/test/TestGlueTest.java index eafba743d..e5d990abf 100644 --- a/src/test/java/kitchenpos/utiltest/TestGlueTest.java +++ b/src/test/java/kitchenpos/util/testglue/test/TestGlueTest.java @@ -1,10 +1,10 @@ -package kitchenpos.utiltest; +package kitchenpos.util.testglue.test; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import kitchenpos.util.EnableTestGlue; -import kitchenpos.util.TestGlue; +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; From ee3c941be6517f615e284441f16f99dbffbab0d9 Mon Sep 17 00:00:00 2001 From: hand Date: Sat, 3 Sep 2022 15:33:23 +0900 Subject: [PATCH 08/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20support=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/testglue/TestGlueContextAware.java | 6 +++++ .../util/testglue/TestGlueInitializer.java | 15 +++++++++-- .../util/testglue/TestGlueSupport.java | 19 ++++++++++++++ .../util/testglue/TestGlueValueContext.java | 26 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/test/java/kitchenpos/util/testglue/TestGlueContextAware.java create mode 100644 src/test/java/kitchenpos/util/testglue/TestGlueSupport.java create mode 100644 src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueContextAware.java b/src/test/java/kitchenpos/util/testglue/TestGlueContextAware.java new file mode 100644 index 000000000..70f0bf665 --- /dev/null +++ b/src/test/java/kitchenpos/util/testglue/TestGlueContextAware.java @@ -0,0 +1,6 @@ +package kitchenpos.util.testglue; + +public interface TestGlueContextAware { + + void testGlueContext(TestGlueValueContext testGlueValueContext); +} diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java index 1a5afb172..083ec7d90 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java @@ -2,11 +2,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Map; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.support.GenericApplicationContext; -import org.springframework.web.bind.annotation.GetMapping; public class TestGlueInitializer implements ApplicationContextAware { @@ -17,6 +17,18 @@ public void setApplicationContext(ApplicationContext applicationContext) throws context.registerBean(TestGlueOperationContext.class); context.registerBean(TestGlue.class); + awareInit(context); + operationInit(context); + } + + private void awareInit(GenericApplicationContext context) { + Map testGlueContextAwares = context.getBeansOfType(TestGlueContextAware.class); + TestGlueValueContext testGlueValueContext = new TestGlueValueContext(); + + testGlueContextAwares.values().forEach(v -> v.testGlueContext(testGlueValueContext)); + } + + private void operationInit(GenericApplicationContext context) { var testGlueOperationContext = context.getBean(TestGlueOperationContext.class); var testGlueConfigurationNames = context.getBeanNamesForAnnotation(TestGlueConfiguration.class); @@ -27,7 +39,6 @@ public void setApplicationContext(ApplicationContext applicationContext) throws } } - @GetMapping("test") private void setTestGlueOperation(Object bean, TestGlueOperationContext testGlueOperationContext) { Method[] methods = bean.getClass().getMethods(); for (Method method : methods) { diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java b/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java new file mode 100644 index 000000000..bce61df95 --- /dev/null +++ b/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java @@ -0,0 +1,19 @@ +package kitchenpos.util.testglue; + +public class TestGlueSupport implements TestGlueContextAware { + + private TestGlueValueContext testGlueValueContext; + + public void put(String key, Object value) { + testGlueValueContext.put(key, value); + } + + public T getAsType(String key, Class type) { + return testGlueValueContext.getAsType(key, type); + } + + @Override + public void testGlueContext(TestGlueValueContext testGlueValueContext) { + this.testGlueValueContext = testGlueValueContext; + } +} diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java b/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java new file mode 100644 index 000000000..69b0b71f2 --- /dev/null +++ b/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java @@ -0,0 +1,26 @@ +package kitchenpos.util.testglue; + +import java.util.HashMap; +import java.util.Map; + +public class TestGlueValueContext { + + private final Map storage; + + public TestGlueValueContext() { + this.storage = new HashMap<>(); + } + + public void put(String key, Object value) { + storage.put(key, value); + } + + public T getAsType(String key, Class type) { + Object o = storage.get(key); + if (o == null) { + throw new IllegalArgumentException(String.format("Cannot found key : %s", key)); + } + + return type.cast(o); + } +} From ce35cba71db65b39baa6ae8397942509fcb2cc60 Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 05:11:48 +0900 Subject: [PATCH 09/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=A9=94=ED=84=B0=20=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kitchenpos/util/testglue/Operation.java | 2 +- .../util/testglue/TestGlueInitializer.java | 20 ++++++-------- .../testglue/TestGlueOperationContext.java | 15 +++++++---- .../util/testglue/TestGlueRunner.java | 26 ++++++++++++++++--- .../test/TestGlueInitializerTest.java | 6 ++--- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/test/java/kitchenpos/util/testglue/Operation.java b/src/test/java/kitchenpos/util/testglue/Operation.java index 8b26a7f22..931db3862 100644 --- a/src/test/java/kitchenpos/util/testglue/Operation.java +++ b/src/test/java/kitchenpos/util/testglue/Operation.java @@ -2,5 +2,5 @@ public interface Operation { - void run(); + void run(Object[] parameters); } diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java index 083ec7d90..48debf86a 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java @@ -46,18 +46,21 @@ private void setTestGlueOperation(Object bean, TestGlueOperationContext testGlue continue; } - validateParameterCount(method); - TestGlueOperation testGlueOperation = method.getAnnotation(TestGlueOperation.class); String description = testGlueOperation.value(); validateDescription(method, description); - testGlueOperationContext.put(description, () -> { + testGlueOperationContext.put(description, parameters -> { try { - method.invoke(bean); + method.invoke(bean, parameters); } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalArgumentException(e); + Throwable cause = e.getCause(); + if (cause instanceof AssertionError) { + throw (AssertionError) cause; + } + + throw new RuntimeException(e); } }); } @@ -68,11 +71,4 @@ private void validateDescription(Method method, String description) { throw new IllegalArgumentException(String.format("Method (%s) description cannot be empty", method.getName())); } } - - private void validateParameterCount(Method method) { - int parameterCount = method.getParameterCount(); - if (parameterCount != 0) { - throw new IllegalArgumentException(String.format("Method (%s) cannot have parameter.", method.getName())); - } - } } diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java b/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java index ab87ee695..e5cb33ccc 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java @@ -20,12 +20,17 @@ public void put(String description, Operation operation) { } public Operation get(String description) { - Operation operation = volume.get(description); - - if (operation == null) { - throw new IllegalArgumentException("can not found operation"); - } + Operation operation = volume.get(find(description)); return operation; } + + private String find(String description) { + final String targetDescription = description.replaceAll("'.*'", "{}"); + + return volume.keySet().stream() + .filter(v -> v.equals(targetDescription)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException(String.format("can not found operation : %s", description))); + } } diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java b/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java index f1dc90cae..700eddeb1 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java @@ -1,9 +1,14 @@ package kitchenpos.util.testglue; +import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class TestGlueRunner { + private static final Pattern tokenPattern = Pattern.compile("('.*')"); + private final TestGlueOperationContext testGlueOperationContext; private final List operations; @@ -13,8 +18,23 @@ public TestGlueRunner(TestGlueOperationContext testGlueOperationContext, List result = new ArrayList<>(); + if (matcher.find()) { + for (int i = 0; i < matcher.groupCount(); i++) { + result.add(matcher.group(i).replaceAll("'", "").trim()); + } + } + + return result.toArray(String[]::new); } } diff --git a/src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java b/src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java index 758b9573c..e60af73d5 100644 --- a/src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java +++ b/src/test/java/kitchenpos/util/testglue/test/TestGlueInitializerTest.java @@ -49,9 +49,9 @@ void testGlueInitialize() { Operation test1 = testGlueOperationContext.get("test1"); Operation test2 = testGlueOperationContext.get("test2"); Operation test3 = testGlueOperationContext.get("test3"); - test1.run(); - test2.run(); - test3.run(); + test1.run(new String[] {}); + test2.run(new String[] {}); + test3.run(new String[] {}); // then assertAll( From b74de49e6e9fe61c40fcececf8e84a264a24cfd0 Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 05:12:06 +0900 Subject: [PATCH 10/21] =?UTF-8?q?test(kitchenpos):=20product=20=EB=B9=84?= =?UTF-8?q?=EC=A6=88=EB=8B=88=EC=8A=A4=20=ED=85=8C=EC=8A=A4=ED=8A=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/ProductServiceTest.java | 46 ++++++++++++++++ .../testglue/fixture/ProductMother.java | 46 ++++++++++++++++ .../product/productTetGlueConfiguration.java | 54 +++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 src/test/java/kitchenpos/application/ProductServiceTest.java create mode 100644 src/test/java/kitchenpos/testglue/fixture/ProductMother.java create mode 100644 src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java diff --git a/src/test/java/kitchenpos/application/ProductServiceTest.java b/src/test/java/kitchenpos/application/ProductServiceTest.java new file mode 100644 index 000000000..4337ff4ea --- /dev/null +++ b/src/test/java/kitchenpos/application/ProductServiceTest.java @@ -0,0 +1,46 @@ +package kitchenpos.application; + +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@EnableTestGlue +@SpringBootTest +class ProductServiceTest { + + @Autowired + private TestGlue testGlue; + + @DisplayName("상품을 생성한다") + @Test + void create() { + testGlue.builder() + .given("'정상상품' 데이터를 생성하고") + .when("'정상상품' 생성을 요청하면") + .then("'정상상품'이 생성된다") + .assertStart(); + } + + @DisplayName("상품의 가격은 비어있으면 안된다.") + @Test + void create_emtpyPrice() { + testGlue.builder() + .given("'가격이 빈 상품' 데이터를 생성하고") + .when("'가격이 빈 상품' 생성을 요청하면") + .then("'가격이 빈 상품'이 생성에 실패한다") + .assertStart(); + } + + @DisplayName("상품의 가격은 음수여서는 안된다.") + @Test + void create_negativePrice() { + testGlue.builder() + .given("'가격이 음수인 상품' 데이터를 생성하고") + .when("'가격이 음수인 상품' 생성을 요청하면") + .then("'가격이 음수인 상품'이 생성에 실패한다") + .assertStart(); + } +} diff --git a/src/test/java/kitchenpos/testglue/fixture/ProductMother.java b/src/test/java/kitchenpos/testglue/fixture/ProductMother.java new file mode 100644 index 000000000..1ddabf7bc --- /dev/null +++ b/src/test/java/kitchenpos/testglue/fixture/ProductMother.java @@ -0,0 +1,46 @@ +package kitchenpos.testglue.fixture; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import kitchenpos.domain.Product; + +public class ProductMother { + + private static final Map values = new HashMap<>(); + + static { + values.put("정상상품", 정상상품()); + values.put("가격이 빈 상품", 가격이_빈_상품()); + values.put("가격이 음수인 상품", 가격이_음수인_상품()); + } + + public static Product findByName(String name) { + return values.get(name); + } + + private static Product 정상상품() { + Product product = new Product(); + product.setPrice(BigDecimal.valueOf(10000)); + product.setName("정상상품"); + + return product; + } + + private static Product 가격이_빈_상품() { + Product product = new Product(); + product.setPrice(null); + product.setName("가격이 빈 상품"); + + return product; + } + + private static Product 가격이_음수인_상품() { + Product product = new Product(); + product.setPrice(BigDecimal.valueOf(-10000)); + product.setName("가격이 음수인 상품"); + + return product; + } +} diff --git a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java new file mode 100644 index 000000000..2501d7570 --- /dev/null +++ b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java @@ -0,0 +1,54 @@ +package kitchenpos.testglue.product; + +import static org.assertj.core.api.Assertions.assertThat; + +import kitchenpos.application.ProductService; +import kitchenpos.domain.Product; +import kitchenpos.domain.ProductRepository; +import kitchenpos.testglue.fixture.ProductMother; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueSupport; + +@TestGlueConfiguration +public class productTetGlueConfiguration extends TestGlueSupport { + + private final ProductService productService; + private final ProductRepository productRepository; + + public productTetGlueConfiguration( + ProductService productService, + ProductRepository productRepository + ) { + this.productService = productService; + this.productRepository = productRepository; + } + + @TestGlueOperation("{} 데이터를 생성하고") + public void create(String name) { + Product 상품 = ProductMother.findByName(name); + + put(name, 상품); + } + + @TestGlueOperation("{} 생성을 요청하면") + public void create_request(String name) { + try { + Product product = productService.create(getAsType(name, Product.class)); + put(name, product); + } catch (Exception ignore) { + } + } + + @TestGlueOperation("{}이 생성된다") + public void create_success(String name) { + Product 상품 = getAsType(name, Product.class); + assertThat(productRepository.findById(상품.getId())).isNotEmpty(); + } + + @TestGlueOperation("{}이 생성에 실패한다") + public void create_fail(String name) { + Product 상품 = getAsType(name, Product.class); + assertThat(상품.getId()).isNull(); + } +} From 1e7030f19788872a32b7fd4a9014cc7c6181799e Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 05:13:44 +0900 Subject: [PATCH 11/21] =?UTF-8?q?test(kitchenpos):=20fixture=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{testglue => application}/fixture/ProductMother.java | 2 +- .../testglue/product/productTetGlueConfiguration.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/test/java/kitchenpos/{testglue => application}/fixture/ProductMother.java (96%) diff --git a/src/test/java/kitchenpos/testglue/fixture/ProductMother.java b/src/test/java/kitchenpos/application/fixture/ProductMother.java similarity index 96% rename from src/test/java/kitchenpos/testglue/fixture/ProductMother.java rename to src/test/java/kitchenpos/application/fixture/ProductMother.java index 1ddabf7bc..7a4252d16 100644 --- a/src/test/java/kitchenpos/testglue/fixture/ProductMother.java +++ b/src/test/java/kitchenpos/application/fixture/ProductMother.java @@ -1,4 +1,4 @@ -package kitchenpos.testglue.fixture; +package kitchenpos.application.fixture; import java.math.BigDecimal; import java.util.HashMap; diff --git a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java index 2501d7570..db04bb46e 100644 --- a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java @@ -5,7 +5,7 @@ import kitchenpos.application.ProductService; import kitchenpos.domain.Product; import kitchenpos.domain.ProductRepository; -import kitchenpos.testglue.fixture.ProductMother; +import kitchenpos.application.fixture.ProductMother; import kitchenpos.util.testglue.TestGlueConfiguration; import kitchenpos.util.testglue.TestGlueOperation; import kitchenpos.util.testglue.TestGlueSupport; From 99a2fcb2c1f44bede65b7a138aeb46aa19bc9483 Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 12:26:33 +0900 Subject: [PATCH 12/21] =?UTF-8?q?test(kitchenpos):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6698f662a..f20615813 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ docker compose -p kitchenpos up -d ### 상품 생성 -- [ ] 상품의 가격은 비어있거나 음수여서는 안된다. -- [ ] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다. +- [x] 상품의 가격은 비어있거나 음수여서는 안된다. +- [x] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다. 가격 변경 - [ ] 가격은 비어있거나 0보다 작아서는 안된다. From 8ad0b7e27e3e71badbfc12f3d7d75a3de77df46c Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 17:42:50 +0900 Subject: [PATCH 13/21] =?UTF-8?q?test(kitchenpos):=20testGlue=20=EB=8B=A4?= =?UTF-8?q?=EC=A4=91=20=ED=8C=8C=EB=9D=BC=EB=A9=94=ED=84=B0=20=EC=A7=80?= =?UTF-8?q?=EC=9B=90.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/testglue/TestGlueOperationContext.java | 2 +- .../java/kitchenpos/util/testglue/TestGlueRunner.java | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java b/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java index e5cb33ccc..f49d6f538 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueOperationContext.java @@ -26,7 +26,7 @@ public Operation get(String description) { } private String find(String description) { - final String targetDescription = description.replaceAll("'.*'", "{}"); + final String targetDescription = description.replaceAll("'[^']*'", "{}"); return volume.keySet().stream() .filter(v -> v.equals(targetDescription)) diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java b/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java index 700eddeb1..839526483 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueRunner.java @@ -7,7 +7,7 @@ public class TestGlueRunner { - private static final Pattern tokenPattern = Pattern.compile("('.*')"); + private static final Pattern tokenPattern = Pattern.compile("('[^']*')"); private final TestGlueOperationContext testGlueOperationContext; private final List operations; @@ -29,10 +29,11 @@ private Object[] extractParameter(String description) { Matcher matcher = tokenPattern.matcher(description); List result = new ArrayList<>(); - if (matcher.find()) { - for (int i = 0; i < matcher.groupCount(); i++) { - result.add(matcher.group(i).replaceAll("'", "").trim()); - } + while (matcher.find()) { + result.add(matcher.group().replaceAll("'", "").trim()); + + description = description.substring(matcher.end()); + matcher = tokenPattern.matcher(description); } return result.toArray(String[]::new); From 8efcf13234285e83d7cc841fce27f34ce4926c34 Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 17:43:10 +0900 Subject: [PATCH 14/21] =?UTF-8?q?test(kitchenpos):=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductServiceTest_changePrice.java | 77 +++++++++++++++++++ ...st.java => ProductServiceTest_create.java} | 2 +- .../application/fixture/ProductMother.java | 10 +++ .../product/productTetGlueConfiguration.java | 55 ++++++++++++- 4 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java rename src/test/java/kitchenpos/application/{ProductServiceTest.java => ProductServiceTest_create.java} (97%) diff --git a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java new file mode 100644 index 000000000..171393805 --- /dev/null +++ b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java @@ -0,0 +1,77 @@ +package kitchenpos.application; + +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@EnableTestGlue +@SpringBootTest +public class ProductServiceTest_changePrice { + + @Autowired + private TestGlue testGlue; + + @DisplayName("상품의 가격을 변경한다.") + @Test + void changePrice() { + testGlue.builder() + .given("'정상상품' 을 생성하고") + .when("'정상상품' 가격을 '2000' 으로 변경하면") + .then("'정상상품' 가격은 변경된다") + .assertStart(); + } + + @DisplayName("상품의 가격을 null로 변경할 순 없다.") + @Test + void changePrice_emptyPrice_null() { + testGlue.builder() + .given("'정상상품' 을 생성하고") + .when("'정상상품' 가격을 'null' 으로 변경하면") + .then("'정상상품' 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("상품의 가격을 비어있게 변경할 순 없다.") + @Test + void changePrice_emptyPrice_blank() { + testGlue.builder() + .given("'정상상품' 을 생성하고") + .when("'정상상품' 가격을 '' 으로 변경하면") + .then("'정상상품' 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("상품의 가격을 0보다 작게 변경할 순 없다.") + @Test + void changePrice_price_less_then_zero() { + testGlue.builder() + .given("'정상상품' 을 생성하고") + .when("'정상상품' 가격을 '-10000' 으로 변경하면") + .then("'정상상품' 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("존재하지 않는 상품을 변경할 순 없다..]") + @Test + void changePrice_no_exist() { + testGlue.builder() + .when("'존재하지 않는 상품' 가격을 '10000' 으로 변경하면") + .then("존재하지 않는 상품 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.") + @Test + void changePrice_menu_constraint() { + // todo 메뉴 테스트 작성 후 + } + + @DisplayName("상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다. 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다.") + @Test + void changePrice_menu_constraint_no_display() { + // todo 메뉴 테스트 작성 후 + } +} diff --git a/src/test/java/kitchenpos/application/ProductServiceTest.java b/src/test/java/kitchenpos/application/ProductServiceTest_create.java similarity index 97% rename from src/test/java/kitchenpos/application/ProductServiceTest.java rename to src/test/java/kitchenpos/application/ProductServiceTest_create.java index 4337ff4ea..c90b4eedd 100644 --- a/src/test/java/kitchenpos/application/ProductServiceTest.java +++ b/src/test/java/kitchenpos/application/ProductServiceTest_create.java @@ -9,7 +9,7 @@ @EnableTestGlue @SpringBootTest -class ProductServiceTest { +class ProductServiceTest_create { @Autowired private TestGlue testGlue; diff --git a/src/test/java/kitchenpos/application/fixture/ProductMother.java b/src/test/java/kitchenpos/application/fixture/ProductMother.java index 7a4252d16..a65ed07e6 100644 --- a/src/test/java/kitchenpos/application/fixture/ProductMother.java +++ b/src/test/java/kitchenpos/application/fixture/ProductMother.java @@ -14,6 +14,7 @@ public class ProductMother { values.put("정상상품", 정상상품()); values.put("가격이 빈 상품", 가격이_빈_상품()); values.put("가격이 음수인 상품", 가격이_음수인_상품()); + values.put("존재하지 않는 상품", 존재하지_않는_상품()); } public static Product findByName(String name) { @@ -43,4 +44,13 @@ public static Product findByName(String name) { return product; } + + private static Product 존재하지_않는_상품() { + Product product= new Product(); + product.setId(UUID.randomUUID()); + product.setPrice(BigDecimal.valueOf(10000)); + product.setName("존재하지 않는 상품"); + + return product; + } } diff --git a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java index db04bb46e..025847a5c 100644 --- a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java @@ -2,10 +2,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.math.BigDecimal; import kitchenpos.application.ProductService; +import kitchenpos.application.fixture.ProductMother; import kitchenpos.domain.Product; import kitchenpos.domain.ProductRepository; -import kitchenpos.application.fixture.ProductMother; import kitchenpos.util.testglue.TestGlueConfiguration; import kitchenpos.util.testglue.TestGlueOperation; import kitchenpos.util.testglue.TestGlueSupport; @@ -25,7 +26,7 @@ public productTetGlueConfiguration( } @TestGlueOperation("{} 데이터를 생성하고") - public void create(String name) { + public void create_data(String name) { Product 상품 = ProductMother.findByName(name); put(name, 상품); @@ -51,4 +52,54 @@ public void create_fail(String name) { Product 상품 = getAsType(name, Product.class); assertThat(상품.getId()).isNull(); } + + @TestGlueOperation("{} 을 생성하고") + public void create(String name) { + Product product = ProductMother.findByName(name); + put(name, productService.create(product)); + } + + @TestGlueOperation("{} 가격을 {} 으로 변경하면") + public void changePrice(String name, String price) { + Product product = getAsType(name, Product.class); + BigDecimal bigDecimalPrice = toBigDecimal(price); + product.setPrice(bigDecimalPrice); + + put("changedPrice", bigDecimalPrice); + + try { + productService.changePrice(product.getId(), product); + } catch (Exception ignore) { + } + } + + @TestGlueOperation("{} 가격은 변경된다") + public void changePrice_result(String name) { + Product product = getAsType(name, Product.class); + Product savedProduct = productRepository.findById(product.getId()).orElseThrow(); + BigDecimal changedPrice = getAsType("changedPrice", BigDecimal.class); + + assertThat(savedProduct.getPrice().longValue()).isEqualTo(changedPrice.longValue()); + } + + @TestGlueOperation("{} 가격 변경에 실패한다") + public void changePrice_result_fail(String name) { + Product product = getAsType(name, Product.class); + Product savedProduct = productRepository.findById(product.getId()).orElseThrow(); + + assertThat(savedProduct.getPrice()).isNotEqualTo(product.getPrice()); + } + + @TestGlueOperation("존재하지 않는 상품 가격 변경에 실패한다") + public void changePrice_no_exist_fail() { + + } + + private BigDecimal toBigDecimal(String price) { + try { + return BigDecimal.valueOf(Long.parseLong(price)); + } catch (NumberFormatException e) { + return null; + } + } } From 960784d34882bc9792aab168f1e352ff001c6a2c Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 17:46:36 +0900 Subject: [PATCH 15/21] =?UTF-8?q?docs(kitchenpos):=20readme=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f20615813..b5e8e9ae6 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ docker compose -p kitchenpos up -d - [x] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다. 가격 변경 -- [ ] 가격은 비어있거나 0보다 작아서는 안된다. -- [ ] 상품은 존재해야 한다. +- [x] 가격은 비어있거나 0보다 작아서는 안된다. +- [x] 상품은 존재해야 한다. - [ ] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.) - [ ] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다. From 3259c682c30f038b375c14464b65bdd53fe39124 Mon Sep 17 00:00:00 2001 From: hand Date: Sun, 4 Sep 2022 18:38:18 +0900 Subject: [PATCH 16/21] =?UTF-8?q?test(kitchenpos):=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EA=B7=B8=EB=A3=B9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- .../application/MenuGroupServiceTest.java | 38 +++++++++++ .../application/fixture/MenuGroupMother.java | 35 ++++++++++ .../menuGroupTestGlueConfiguration.java | 66 +++++++++++++++++++ 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/test/java/kitchenpos/application/MenuGroupServiceTest.java create mode 100644 src/test/java/kitchenpos/application/fixture/MenuGroupMother.java create mode 100644 src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java diff --git a/README.md b/README.md index b5e8e9ae6..6066ff8ff 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ docker compose -p kitchenpos up -d ## 요구 사항 ### 메뉴 그룹 -- [ ] 메뉴 그룹은 N개의 메뉴를 가질 수 있다. -- [ ] 메뉴그룹 이름은 비어있을 수 없다. +- [x] 메뉴 그룹은 N개의 메뉴를 가질 수 있다. +- [x] 메뉴그룹 이름은 비어있을 수 없다. ### 메뉴 - 생성 diff --git a/src/test/java/kitchenpos/application/MenuGroupServiceTest.java b/src/test/java/kitchenpos/application/MenuGroupServiceTest.java new file mode 100644 index 000000000..0b9c30a14 --- /dev/null +++ b/src/test/java/kitchenpos/application/MenuGroupServiceTest.java @@ -0,0 +1,38 @@ +package kitchenpos.application; + +import static org.junit.jupiter.api.Assertions.*; + +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@EnableTestGlue +@SpringBootTest +class MenuGroupServiceTest { + + @Autowired + private TestGlue testGlue; + + @DisplayName("메뉴그룹을 생성한다.") + @Test + void create() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴그룹 데이터를 만들고") + .when("'추천메뉴그룹' 메뉴그룹 생성을 요청하면") + .then("'추천메뉴그룹' 메뉴그룹이 생성된다") + .assertStart(); + } + + @DisplayName("메뉴그룹 이름은 비어있을 수 없다.") + @Test + void create_emptyName() { + testGlue.builder() + .given("'이름이 빈 메뉴그룹' 메뉴그룹 데이터를 만들고") + .when("'이름이 빈 메뉴그룹' 메뉴그룹 생성을 요청하면") + .then("'이름이 빈 메뉴그룹' 메뉴그룹 생성에 실패한다") + .assertStart(); + } +} diff --git a/src/test/java/kitchenpos/application/fixture/MenuGroupMother.java b/src/test/java/kitchenpos/application/fixture/MenuGroupMother.java new file mode 100644 index 000000000..3c4b747a0 --- /dev/null +++ b/src/test/java/kitchenpos/application/fixture/MenuGroupMother.java @@ -0,0 +1,35 @@ +package kitchenpos.application.fixture; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import kitchenpos.domain.MenuGroup; + +public class MenuGroupMother { + + private static final Map values = new HashMap<>(); + + static { + values.put("추천메뉴그룹", 추천메뉴그룹()); + values.put("이름이 빈 메뉴그룹", 이름이_빈_메뉴그룹()); + } + + public static MenuGroup findByName(String name) { + return values.get(name); + } + + private static MenuGroup 추천메뉴그룹() { + MenuGroup menuGroup = new MenuGroup(); + menuGroup.setName("추천메뉴그룹"); + + return menuGroup; + } + + private static MenuGroup 이름이_빈_메뉴그룹() { + MenuGroup menuGroup = new MenuGroup(); + menuGroup.setId(UUID.randomUUID()); + menuGroup.setName(""); + + return menuGroup; + } +} diff --git a/src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java new file mode 100644 index 000000000..923de1cc6 --- /dev/null +++ b/src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java @@ -0,0 +1,66 @@ +package kitchenpos.testglue.menugroup; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.util.Optional; +import kitchenpos.application.MenuGroupService; +import kitchenpos.application.ProductService; +import kitchenpos.application.fixture.MenuGroupMother; +import kitchenpos.application.fixture.ProductMother; +import kitchenpos.domain.MenuGroup; +import kitchenpos.domain.MenuGroupRepository; +import kitchenpos.domain.Product; +import kitchenpos.domain.ProductRepository; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueSupport; + +@TestGlueConfiguration +public class menuGroupTestGlueConfiguration extends TestGlueSupport { + + private final MenuGroupService menuGroupService; + private final MenuGroupRepository menuGroupRepository; + + public menuGroupTestGlueConfiguration( + MenuGroupService menuGroupService, + MenuGroupRepository menuGroupRepository + ) { + this.menuGroupService = menuGroupService; + this.menuGroupRepository = menuGroupRepository; + } + + @TestGlueOperation("{} 메뉴그룹 데이터를 만들고") + public void create_data(String name) { + MenuGroup menuGroup = MenuGroupMother.findByName(name); + + put(name, menuGroup); + } + + @TestGlueOperation("{} 메뉴그룹 생성을 요청하면") + public void create_request(String name) { + try { + MenuGroup menuGroup = getAsType(name, MenuGroup.class); + + MenuGroup savedMenuGroup = menuGroupService.create(menuGroup); + put(name, savedMenuGroup); + } catch (Exception ignore) { + } + } + + @TestGlueOperation("{} 메뉴그룹이 생성된다") + public void create(String name) { + MenuGroup menuGroup = getAsType(name, MenuGroup.class); + + Optional savedMenuGroup = menuGroupRepository.findById(menuGroup.getId()); + assertThat(savedMenuGroup).isNotEmpty(); + } + + @TestGlueOperation("{} 메뉴그룹 생성에 실패한다") + public void create_fail(String name) { + MenuGroup menuGroup = getAsType(name, MenuGroup.class); + + Optional savedMenuGroup = menuGroupRepository.findById(menuGroup.getId()); + assertThat(savedMenuGroup).isEmpty(); + } +} From a88fc1cb6ee8ea57a4b3a36bdd7233642c012981 Mon Sep 17 00:00:00 2001 From: hand Date: Mon, 19 Sep 2022 20:16:32 +0900 Subject: [PATCH 17/21] =?UTF-8?q?test(kitchenpos):=20=EA=B9=A8=EC=A7=80?= =?UTF-8?q?=EB=8A=90=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +- .../application/MenuServiceTest.java | 159 ++++++++++++++++++ .../ProductServiceTest_changePrice.java | 32 ++-- .../ProductServiceTest_create.java | 18 +- .../application/fixture/MenuMother.java | 57 +++++++ .../application/fixture/ProductMother.java | 11 ++ .../PurgomalumClientConfiguration.java | 26 +++ .../menu/MenuTestGlueConfiguration.java | 142 ++++++++++++++++ ...va => MenuGroupTestGlueConfiguration.java} | 37 ++-- .../product/ProductTestGlueConfiguration.java | 124 ++++++++++++++ .../product/productTetGlueConfiguration.java | 105 ------------ .../util/testglue/TestGlueInitializer.java | 11 +- .../util/testglue/TestGlueSupport.java | 20 +++ .../util/testglue/TestGlueValueContext.java | 2 +- .../util/testglue/test/TestGlueResponse.java | 36 ++++ 15 files changed, 637 insertions(+), 159 deletions(-) create mode 100644 src/test/java/kitchenpos/application/MenuServiceTest.java create mode 100644 src/test/java/kitchenpos/application/fixture/MenuMother.java create mode 100644 src/test/java/kitchenpos/configuration/PurgomalumClientConfiguration.java create mode 100644 src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java rename src/test/java/kitchenpos/testglue/menugroup/{menuGroupTestGlueConfiguration.java => MenuGroupTestGlueConfiguration.java} (65%) create mode 100644 src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java delete mode 100644 src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java create mode 100644 src/test/java/kitchenpos/util/testglue/test/TestGlueResponse.java diff --git a/README.md b/README.md index 6066ff8ff..a7a433a12 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ docker compose -p kitchenpos up -d ### 메뉴 - 생성 -- [ ] 메뉴 가격은 비어있을 수 없다. -- [ ] 메뉴 가격은 음수일 수 없다. -- [ ] 메뉴는 특정 메뉴 그룹에 항상 속해야 한다. -- [ ] 메뉴는 N 개의 메뉴 상품을 가진다. -- [ ] 메뉴에 속한 상품은 모두 존재해야 한다. -- [ ] 메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다. -- [ ] 메뉴 이름은 비어있을 수 없다. -- [ ] 메뉴 이름에는 욕설이 포함될 수 없다. +- [x] 메뉴 가격은 비어있을 수 없다. +- [x] 메뉴 가격은 음수일 수 없다. +- [x] 메뉴는 특정 메뉴 그룹에 항상 속해야 한다. +- [x] 메뉴는 N 개의 메뉴 상품을 가진다. +- [x] 메뉴에 속한 상품은 모두 존재해야 한다. +- [x] 메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다. +- [x] 메뉴 이름은 비어있을 수 없다. +- [x] 메뉴 이름에는 욕설이 포함될 수 없다. - 가격 변경 - [ ] 가격은 비어있거나 음수일 수 없다. diff --git a/src/test/java/kitchenpos/application/MenuServiceTest.java b/src/test/java/kitchenpos/application/MenuServiceTest.java new file mode 100644 index 000000000..0ea407394 --- /dev/null +++ b/src/test/java/kitchenpos/application/MenuServiceTest.java @@ -0,0 +1,159 @@ +package kitchenpos.application; + +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@EnableTestGlue +class MenuServiceTest { + + @Autowired + private TestGlue testGlue; + + @DisplayName("메뉴를 생성한다.") + @Test + void create() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .when("'추천메뉴' 메뉴 생성을 요청하면") + .then("'추천메뉴' 메뉴가 생성된다") + .assertStart(); + } + + @DisplayName("메뉴 가격은 비어있을 수 없다.") + @Test + void create_emptyPrice() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '가격이 빈 메뉴' 메뉴 데이터를 만들고") + .when("'가격이 빈 메뉴' 메뉴 생성을 요청하면") + .then("'가격이 빈 메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("메뉴 가격은 음수일 수 없다.") + @Test + void create_negativePrice() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '가격이 음수인 메뉴' 메뉴 데이터를 만들고") + .when("'가격이 음수인 메뉴' 메뉴 생성을 요청하면") + .then("'가격이 음수인 메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("메뉴는 특정 메뉴 그룹에 항상 속해야 한다.") + @Test + void create_notIncludedInMenuGroup() { + testGlue.builder() + .given("'상품1' 상품을 생성하고") + .given("'없는 그룹'에 속하고 '상품1' '3'개를 이용해 '메뉴그룹이 없는 메뉴' 메뉴 데이터를 만들고") + .when("'메뉴그룹이 없는 메뉴' 메뉴 생성을 요청하면") + .then("'메뉴그룹이 없는 메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("메뉴에 속한 상품은 모두 존재해야 한다.") + @Test + void create_get_N_menuProduct() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'추천메뉴그룹'에 속하고 '없는상품' '3'개를 이용해 '메뉴 상품이 없는 메뉴' 메뉴 데이터를 만들고") + .when("'메뉴 상품이 없는 메뉴' 메뉴 생성을 요청하면") + .then("'메뉴 상품이 없는 메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다.") + @Test + void create_menu_price_constraint() { + testGlue.builder() + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '비싼메뉴' 메뉴 데이터를 만들고") + .when("'비싼메뉴' 메뉴 생성을 요청하면") + .then("'비싼메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("메뉴 이름은 비어있을 수 없다.") + @Test + void create_empty_name() { + testGlue.builder() + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '이름이 빈 메뉴' 메뉴 데이터를 만들고") + .when("'이름이 빈 메뉴' 메뉴 생성을 요청하면") + .then("'이름이 빈 메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("메뉴 이름에는 욕설이 포함될 수 없다.") + @Test + void create_2() { + testGlue.builder() + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '욕설이 포함된 메뉴' 메뉴 데이터를 만들고") + .when("'욕설이 포함된 메뉴' 메뉴 생성을 요청하면") + .then("'욕설이 포함된 메뉴' 메뉴 생성에 실패한다") + .assertStart(); + } + + @DisplayName("가격은 비어있을 수 없다.") + @Test + void changePrice_empty() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'추천메뉴' 메뉴 가격을 '' 로 변경하면") + .then("'추천메뉴' 메뉴 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("가격은 음수일 수 없다.") + @Test + void changePrice_negative() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'추천메뉴' 메뉴 가격을 '-10000' 로 변경하면") + .then("'추천메뉴' 메뉴 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다.") + @Test + void changePrice_exist_menu() { + testGlue.builder() + .when("없는메뉴 메뉴 가격을 '20000' 로 변경하면") + .then("없는메뉴 메뉴 가격 변경에 실패한다") + .assertStart(); + } + + @DisplayName("변경하고자 하는 가격이 현재 가격과 같아선 안된다.") + @Test + void changePrice() { + + } + + @Test + void display() { + } + + @Test + void hide() { + } +} diff --git a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java index 171393805..b8372efb4 100644 --- a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java +++ b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java @@ -9,7 +9,7 @@ @EnableTestGlue @SpringBootTest -public class ProductServiceTest_changePrice { +class ProductServiceTest_changePrice { @Autowired private TestGlue testGlue; @@ -18,9 +18,9 @@ public class ProductServiceTest_changePrice { @Test void changePrice() { testGlue.builder() - .given("'정상상품' 을 생성하고") - .when("'정상상품' 가격을 '2000' 으로 변경하면") - .then("'정상상품' 가격은 변경된다") + .given("'정상상품' 상품을 생성하고") + .when("'정상상품' 상품 가격을 '2000' 으로 변경하면") + .then("'정상상품' 상품 가격은 변경된다") .assertStart(); } @@ -28,9 +28,9 @@ void changePrice() { @Test void changePrice_emptyPrice_null() { testGlue.builder() - .given("'정상상품' 을 생성하고") - .when("'정상상품' 가격을 'null' 으로 변경하면") - .then("'정상상품' 가격 변경에 실패한다") + .given("'정상상품' 상품을 생성하고") + .when("'정상상품' 상품 가격을 'null' 으로 변경하면") + .then("'정상상품' 상품 가격 변경에 실패한다") .assertStart(); } @@ -38,9 +38,9 @@ void changePrice_emptyPrice_null() { @Test void changePrice_emptyPrice_blank() { testGlue.builder() - .given("'정상상품' 을 생성하고") - .when("'정상상품' 가격을 '' 으로 변경하면") - .then("'정상상품' 가격 변경에 실패한다") + .given("'정상상품' 상품을 생성하고") + .when("'정상상품' 상품 가격을 '' 으로 변경하면") + .then("'정상상품' 상품 가격 변경에 실패한다") .assertStart(); } @@ -48,18 +48,18 @@ void changePrice_emptyPrice_blank() { @Test void changePrice_price_less_then_zero() { testGlue.builder() - .given("'정상상품' 을 생성하고") - .when("'정상상품' 가격을 '-10000' 으로 변경하면") - .then("'정상상품' 가격 변경에 실패한다") + .given("'정상상품' 상품을 생성하고") + .when("'정상상품' 상품 가격을 '-10000' 으로 변경하면") + .then("'정상상품' 상품 가격 변경에 실패한다") .assertStart(); } - @DisplayName("존재하지 않는 상품을 변경할 순 없다..]") + @DisplayName("존재하지 않는 상품을 변경할 순 없다.") @Test void changePrice_no_exist() { testGlue.builder() - .when("'존재하지 않는 상품' 가격을 '10000' 으로 변경하면") - .then("존재하지 않는 상품 가격 변경에 실패한다") + .when("존재하지 않는 상품 상품 가격을 '10000' 으로 변경하면") + .then("존재하지 않는 상품 상품 가격 변경에 실패한다") .assertStart(); } diff --git a/src/test/java/kitchenpos/application/ProductServiceTest_create.java b/src/test/java/kitchenpos/application/ProductServiceTest_create.java index c90b4eedd..c975de385 100644 --- a/src/test/java/kitchenpos/application/ProductServiceTest_create.java +++ b/src/test/java/kitchenpos/application/ProductServiceTest_create.java @@ -18,9 +18,9 @@ class ProductServiceTest_create { @Test void create() { testGlue.builder() - .given("'정상상품' 데이터를 생성하고") - .when("'정상상품' 생성을 요청하면") - .then("'정상상품'이 생성된다") + .given("'정상상품' 상품 데이터를 생성하고") + .when("'정상상품' 상품 생성을 요청하면") + .then("'정상상품' 상품이 생성된다") .assertStart(); } @@ -28,9 +28,9 @@ void create() { @Test void create_emtpyPrice() { testGlue.builder() - .given("'가격이 빈 상품' 데이터를 생성하고") - .when("'가격이 빈 상품' 생성을 요청하면") - .then("'가격이 빈 상품'이 생성에 실패한다") + .given("'가격이 빈 상품' 상품 데이터를 생성하고") + .when("'가격이 빈 상품' 상품 생성을 요청하면") + .then("'가격이 빈 상품' 상품이 생성에 실패한다") .assertStart(); } @@ -38,9 +38,9 @@ void create_emtpyPrice() { @Test void create_negativePrice() { testGlue.builder() - .given("'가격이 음수인 상품' 데이터를 생성하고") - .when("'가격이 음수인 상품' 생성을 요청하면") - .then("'가격이 음수인 상품'이 생성에 실패한다") + .given("'가격이 음수인 상품' 상품 데이터를 생성하고") + .when("'가격이 음수인 상품' 상품 생성을 요청하면") + .then("'가격이 음수인 상품' 상품이 생성에 실패한다") .assertStart(); } } diff --git a/src/test/java/kitchenpos/application/fixture/MenuMother.java b/src/test/java/kitchenpos/application/fixture/MenuMother.java new file mode 100644 index 000000000..94186341e --- /dev/null +++ b/src/test/java/kitchenpos/application/fixture/MenuMother.java @@ -0,0 +1,57 @@ +package kitchenpos.application.fixture; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import kitchenpos.domain.Menu; +import kitchenpos.domain.MenuGroup; +import kitchenpos.domain.MenuProduct; + +public class MenuMother { + + public static final Map creators = new HashMap<>(); + + static { + creators.put("추천메뉴", (name, menuGroup, menuProducts) -> 메뉴(name, 9000L, menuGroup, menuProducts)); + creators.put("가격이 빈 메뉴", (name, menuGroup, menuProducts) -> 메뉴(name, null, menuGroup, menuProducts)); + creators.put("가격이 음수인 메뉴", (name, menuGroup, menuProducts) -> 메뉴(name, -10000L, menuGroup, menuProducts)); + creators.put("비싼메뉴", (name, menuGroup, menuProducts) -> 메뉴(name, 1000000L, menuGroup, menuProducts)); + creators.put("이름이 빈 메뉴", (name, menuGroup, menuProducts) -> 메뉴("", 10000L, menuGroup, menuProducts)); + creators.put("욕설이 포함된 메뉴", (name, menuGroup, menuProducts) -> 메뉴("suck", 10000L, menuGroup, menuProducts)); + creators.put("메뉴그룹이 없는 메뉴", (name, menuGroup, menuProducts) -> 메뉴(name, 10000L, menuGroup, menuProducts)); + creators.put("메뉴 상품이 없는 메뉴", (name, menuGroup, menuProducts) -> 메뉴(name, 10000L, menuGroup, menuProducts)); + } + + public static CreateMenu findCreatorByName(String name) { + return creators.get(name); + } + + private static Menu 메뉴( + String name, + Long price, + MenuGroup menuGroup, + List menuProducts + ) { + Menu menu = new Menu(); + menu.setId(UUID.randomUUID()); + menu.setName(name); + if (price != null) { + menu.setPrice(BigDecimal.valueOf(price)); + } + menu.setMenuGroup(menuGroup); + menu.setDisplayed(true); + menu.setMenuProducts(menuProducts); + if (menuGroup != null) { + menu.setMenuGroupId(menuGroup.getId()); + } + + return menu; + } + + public interface CreateMenu { + + Menu create(String name, MenuGroup menuGroup, List menuProducts); + } +} diff --git a/src/test/java/kitchenpos/application/fixture/ProductMother.java b/src/test/java/kitchenpos/application/fixture/ProductMother.java index a65ed07e6..0b1dd9f7d 100644 --- a/src/test/java/kitchenpos/application/fixture/ProductMother.java +++ b/src/test/java/kitchenpos/application/fixture/ProductMother.java @@ -15,6 +15,9 @@ public class ProductMother { values.put("가격이 빈 상품", 가격이_빈_상품()); values.put("가격이 음수인 상품", 가격이_음수인_상품()); values.put("존재하지 않는 상품", 존재하지_않는_상품()); + values.put("상품1", 상품("상품1")); + values.put("상품2", 상품("상품2")); + values.put("상품3", 상품("상품3")); } public static Product findByName(String name) { @@ -53,4 +56,12 @@ public static Product findByName(String name) { return product; } + + private static Product 상품(String name) { + Product product = new Product(); + product.setPrice(BigDecimal.valueOf(3000)); + product.setName(name); + + return product; + } } diff --git a/src/test/java/kitchenpos/configuration/PurgomalumClientConfiguration.java b/src/test/java/kitchenpos/configuration/PurgomalumClientConfiguration.java new file mode 100644 index 000000000..41fe91c6e --- /dev/null +++ b/src/test/java/kitchenpos/configuration/PurgomalumClientConfiguration.java @@ -0,0 +1,26 @@ +package kitchenpos.configuration; + +import static org.mockito.BDDMockito.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +import kitchenpos.infra.PurgomalumClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.ActiveProfiles; + +@Configuration +@ActiveProfiles("test") +public class PurgomalumClientConfiguration { + + @Bean + @Primary + public PurgomalumClient testPurgomalumClient() { + PurgomalumClient purgomalumClient = mock(PurgomalumClient.class); + + given(purgomalumClient.containsProfanity(any())).willReturn(false); + + return purgomalumClient; + } +} diff --git a/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java new file mode 100644 index 000000000..ee7a974e9 --- /dev/null +++ b/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java @@ -0,0 +1,142 @@ +package kitchenpos.testglue.menu; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.util.List; +import java.util.UUID; +import kitchenpos.application.MenuService; +import kitchenpos.application.fixture.MenuMother; +import kitchenpos.domain.Menu; +import kitchenpos.domain.MenuGroup; +import kitchenpos.domain.MenuProduct; +import kitchenpos.domain.MenuRepository; +import kitchenpos.domain.Product; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueSupport; +import kitchenpos.util.testglue.test.TestGlueResponse; + +@TestGlueConfiguration +public class MenuTestGlueConfiguration extends TestGlueSupport { + + private final MenuService menuService; + private final MenuRepository menuRepository; + + public MenuTestGlueConfiguration( + MenuService menuService, + MenuRepository menuRepository + ) { + this.menuService = menuService; + this.menuRepository = menuRepository; + } + + @TestGlueOperation("{}에 속하고 {} {}개를 이용해 {} 메뉴 데이터를 만들고") + public void create_data( + String menuGroupName, + String productName, + String productQuantity, + String name + ) { + MenuGroup menuGroup = getAsType(menuGroupName, MenuGroup.class); + Product product = getAsType(productName, Product.class); + + MenuProduct menuProduct = new MenuProduct(); + menuProduct.setProduct(product); + menuProduct.setQuantity(toLong(productQuantity)); + if (product != null) { + menuProduct.setProductId(product.getId()); + } + + Menu menuRequest = MenuMother.findCreatorByName(name).create(name, menuGroup, List.of(menuProduct)); + + put(name, menuRequest); + + } + + @TestGlueOperation("{} 메뉴를 생성하고") + public void create_request_given(String name) { + Menu menu = getAsType(name, Menu.class); + + Menu savedMenu = menuService.create(menu); + + put(name, savedMenu); + } + + @TestGlueOperation("{} 메뉴 생성을 요청하면") + public void create_request_when(String name) { + Menu menu = getAsType(name, Menu.class); + + TestGlueResponse response = createResponse(() -> menuService.create(menu)); + + put(name, response); + } + + @TestGlueOperation("{} 메뉴가 생성된다") + public void create(String name) { + TestGlueResponse response = getAsType(name, TestGlueResponse.class); + + Menu menu = response.getData(); + assertThat(menuRepository.findById(menu.getId())).isNotEmpty(); + } + + @TestGlueOperation("{} 메뉴 생성에 실패한다") + public void create_fail(String name) { + TestGlueResponse response = getAsType(name, TestGlueResponse.class); + + assertThat(response.isOk()).isFalse(); + } + + @TestGlueOperation("{} 메뉴 가격을 {} 로 변경하면") + public void changePrice_exist_menu(String name, String price) { + put("changePrice", toLong(price)); + + Menu menu = getAsType(name, Menu.class); + menu.setPrice(toBigDecimal(price)); + + TestGlueResponse response = createResponse(() -> menuService.changePrice(menu.getId(), menu)); + put("changePriceResponse", response); + } + + @TestGlueOperation("없는메뉴 메뉴 가격을 {} 로 변경하면") + public void changePrice_not_exist_menu(String price) { + Menu menu = new Menu(); + menu.setPrice(toBigDecimal(price)); + TestGlueResponse response = createResponse(() -> menuService.changePrice(UUID.randomUUID(), menu)); + put("changePriceResponse", response); + } + + @TestGlueOperation("{} 메뉴 가격 변경에 실패한다") + public void changePrice(String name) { + TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + assertThat(changePriceResponse.isOk()).isFalse(); + + Long price = getAsType("changePrice", Long.class); + Menu menu = getAsType(name, Menu.class); + Menu savedMenu = menuRepository.findById(menu.getId()).orElseThrow(); + + assertThat(savedMenu.getPrice().longValue()).isNotEqualTo(price); + } + + @TestGlueOperation("없는메뉴 메뉴 가격 변경에 실패한다") + public void notExistMenu_changePrice() { + TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + assertThat(changePriceResponse.isOk()).isFalse(); + } + + private Long toLong(String price) { + try { + return Long.parseLong(price); + } catch (Exception e) { + return null; + } + } + + private BigDecimal toBigDecimal(String price) { + try { + return BigDecimal.valueOf(Long.parseLong(price)); + } catch (NumberFormatException e) { + return null; + } + } +} diff --git a/src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/menugroup/MenuGroupTestGlueConfiguration.java similarity index 65% rename from src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java rename to src/test/java/kitchenpos/testglue/menugroup/MenuGroupTestGlueConfiguration.java index 923de1cc6..8d6e25bec 100644 --- a/src/test/java/kitchenpos/testglue/menugroup/menuGroupTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/menugroup/MenuGroupTestGlueConfiguration.java @@ -2,27 +2,23 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.math.BigDecimal; import java.util.Optional; import kitchenpos.application.MenuGroupService; -import kitchenpos.application.ProductService; import kitchenpos.application.fixture.MenuGroupMother; -import kitchenpos.application.fixture.ProductMother; import kitchenpos.domain.MenuGroup; import kitchenpos.domain.MenuGroupRepository; -import kitchenpos.domain.Product; -import kitchenpos.domain.ProductRepository; import kitchenpos.util.testglue.TestGlueConfiguration; import kitchenpos.util.testglue.TestGlueOperation; import kitchenpos.util.testglue.TestGlueSupport; +import kitchenpos.util.testglue.test.TestGlueResponse; @TestGlueConfiguration -public class menuGroupTestGlueConfiguration extends TestGlueSupport { +public class MenuGroupTestGlueConfiguration extends TestGlueSupport { private final MenuGroupService menuGroupService; private final MenuGroupRepository menuGroupRepository; - public menuGroupTestGlueConfiguration( + public MenuGroupTestGlueConfiguration( MenuGroupService menuGroupService, MenuGroupRepository menuGroupRepository ) { @@ -30,6 +26,14 @@ public menuGroupTestGlueConfiguration( this.menuGroupRepository = menuGroupRepository; } + @TestGlueOperation("{} 메뉴 그룹을 생성하고") + public void create_menu_group(String name) { + MenuGroup menuGroup = MenuGroupMother.findByName(name); + MenuGroup savedMenuGroup = menuGroupService.create(menuGroup); + + put(name, savedMenuGroup); + } + @TestGlueOperation("{} 메뉴그룹 데이터를 만들고") public void create_data(String name) { MenuGroup menuGroup = MenuGroupMother.findByName(name); @@ -39,18 +43,18 @@ public void create_data(String name) { @TestGlueOperation("{} 메뉴그룹 생성을 요청하면") public void create_request(String name) { - try { - MenuGroup menuGroup = getAsType(name, MenuGroup.class); - MenuGroup savedMenuGroup = menuGroupService.create(menuGroup); - put(name, savedMenuGroup); - } catch (Exception ignore) { - } + MenuGroup menuGroup = getAsType(name, MenuGroup.class); + + TestGlueResponse response = createResponse(() -> menuGroupService.create(menuGroup)); + put(name, response); } @TestGlueOperation("{} 메뉴그룹이 생성된다") public void create(String name) { - MenuGroup menuGroup = getAsType(name, MenuGroup.class); + TestGlueResponse response = getAsType(name, TestGlueResponse.class); + + MenuGroup menuGroup = response.getData(); Optional savedMenuGroup = menuGroupRepository.findById(menuGroup.getId()); assertThat(savedMenuGroup).isNotEmpty(); @@ -58,9 +62,8 @@ public void create(String name) { @TestGlueOperation("{} 메뉴그룹 생성에 실패한다") public void create_fail(String name) { - MenuGroup menuGroup = getAsType(name, MenuGroup.class); + TestGlueResponse response = getAsType(name, TestGlueResponse.class); - Optional savedMenuGroup = menuGroupRepository.findById(menuGroup.getId()); - assertThat(savedMenuGroup).isEmpty(); + assertThat(response.isOk()).isFalse(); } } diff --git a/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java new file mode 100644 index 000000000..fa94afff4 --- /dev/null +++ b/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java @@ -0,0 +1,124 @@ +package kitchenpos.testglue.product; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.util.UUID; +import kitchenpos.application.ProductService; +import kitchenpos.application.fixture.ProductMother; +import kitchenpos.domain.Product; +import kitchenpos.domain.ProductRepository; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueSupport; +import kitchenpos.util.testglue.test.TestGlueResponse; + +@TestGlueConfiguration +public class ProductTestGlueConfiguration extends TestGlueSupport { + + private final ProductService productService; + private final ProductRepository productRepository; + + public ProductTestGlueConfiguration( + ProductService productService, + ProductRepository productRepository + ) { + this.productService = productService; + this.productRepository = productRepository; + } + + @TestGlueOperation("{} 상품 데이터를 생성하고") + public void create_data(String name) { + Product 상품 = ProductMother.findByName(name); + + put(name, 상품); + } + + @TestGlueOperation("{} 상품 생성을 요청하면") + public void create_request(String name) { + + TestGlueResponse response = createResponse(() -> productService.create(getAsType(name, Product.class))); + + put(name, response); + } + + @TestGlueOperation("{} 상품이 생성된다") + public void create_success(String name) { + TestGlueResponse response = getAsType(name, TestGlueResponse.class); + + Product product = response.getData(); + + assertThat(productRepository.findById(product.getId())).isNotEmpty(); + } + + @TestGlueOperation("{} 상품이 생성에 실패한다") + public void create_fail(String name) { + TestGlueResponse response = getAsType(name, TestGlueResponse.class); + + assertThat(response.isOk()).isFalse(); + } + + @TestGlueOperation("{} 상품을 생성하고") + public void create(String name) { + Product product = ProductMother.findByName(name); + put(name, productService.create(product)); + } + + @TestGlueOperation("{} 상품 가격을 {} 으로 변경하면") + public void changePrice(String name, String price) { + Product product = getAsType(name, Product.class); + BigDecimal bigDecimalPrice = toBigDecimal(price); + product.setPrice(bigDecimalPrice); + + put("changedPrice", bigDecimalPrice); + + TestGlueResponse response = createResponse(() -> productService.changePrice(product.getId(), product)); + put("changePriceResponse", response); + } + + @TestGlueOperation("존재하지 않는 상품 상품 가격을 {} 으로 변경하면") + public void notExistProduct_changePrice(String price) { + Product product = new Product(); + product.setPrice(toBigDecimal(price)); + TestGlueResponse response = createResponse(() -> productService.changePrice(UUID.randomUUID(), product)); + + put("changePriceResponse", response); + } + + @TestGlueOperation("{} 상품 가격은 변경된다") + public void changePrice_result(String name) { + TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + assertThat(changePriceResponse.isOk()).isTrue(); + + Product product = getAsType(name, Product.class); + Product savedProduct = productRepository.findById(product.getId()).orElseThrow(); + BigDecimal changedPrice = getAsType("changedPrice", BigDecimal.class); + + assertThat(savedProduct.getPrice().longValue()).isEqualTo(changedPrice.longValue()); + } + + @TestGlueOperation("{} 상품 가격 변경에 실패한다") + public void changePrice_result_fail(String name) { + TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + assertThat(changePriceResponse.isOk()).isFalse(); + + Product product = getAsType(name, Product.class); + Product savedProduct = productRepository.findById(product.getId()).orElseThrow(); + + assertThat(savedProduct.getPrice()).isNotEqualTo(product.getPrice()); + } + + @TestGlueOperation("존재하지 않는 상품 상품 가격 변경에 실패한다") + public void notExistProduct_changePrice_result() { + TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + assertThat(changePriceResponse.isOk()).isFalse(); + } + + private BigDecimal toBigDecimal(String price) { + try { + return BigDecimal.valueOf(Long.parseLong(price)); + } catch (NumberFormatException e) { + return null; + } + } +} diff --git a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java b/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java deleted file mode 100644 index 025847a5c..000000000 --- a/src/test/java/kitchenpos/testglue/product/productTetGlueConfiguration.java +++ /dev/null @@ -1,105 +0,0 @@ -package kitchenpos.testglue.product; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.math.BigDecimal; -import kitchenpos.application.ProductService; -import kitchenpos.application.fixture.ProductMother; -import kitchenpos.domain.Product; -import kitchenpos.domain.ProductRepository; -import kitchenpos.util.testglue.TestGlueConfiguration; -import kitchenpos.util.testglue.TestGlueOperation; -import kitchenpos.util.testglue.TestGlueSupport; - -@TestGlueConfiguration -public class productTetGlueConfiguration extends TestGlueSupport { - - private final ProductService productService; - private final ProductRepository productRepository; - - public productTetGlueConfiguration( - ProductService productService, - ProductRepository productRepository - ) { - this.productService = productService; - this.productRepository = productRepository; - } - - @TestGlueOperation("{} 데이터를 생성하고") - public void create_data(String name) { - Product 상품 = ProductMother.findByName(name); - - put(name, 상품); - } - - @TestGlueOperation("{} 생성을 요청하면") - public void create_request(String name) { - try { - Product product = productService.create(getAsType(name, Product.class)); - put(name, product); - } catch (Exception ignore) { - } - } - - @TestGlueOperation("{}이 생성된다") - public void create_success(String name) { - Product 상품 = getAsType(name, Product.class); - assertThat(productRepository.findById(상품.getId())).isNotEmpty(); - } - - @TestGlueOperation("{}이 생성에 실패한다") - public void create_fail(String name) { - Product 상품 = getAsType(name, Product.class); - assertThat(상품.getId()).isNull(); - } - - @TestGlueOperation("{} 을 생성하고") - public void create(String name) { - Product product = ProductMother.findByName(name); - put(name, productService.create(product)); - } - - @TestGlueOperation("{} 가격을 {} 으로 변경하면") - public void changePrice(String name, String price) { - Product product = getAsType(name, Product.class); - BigDecimal bigDecimalPrice = toBigDecimal(price); - product.setPrice(bigDecimalPrice); - - put("changedPrice", bigDecimalPrice); - - try { - productService.changePrice(product.getId(), product); - } catch (Exception ignore) { - } - } - - @TestGlueOperation("{} 가격은 변경된다") - public void changePrice_result(String name) { - Product product = getAsType(name, Product.class); - Product savedProduct = productRepository.findById(product.getId()).orElseThrow(); - BigDecimal changedPrice = getAsType("changedPrice", BigDecimal.class); - - assertThat(savedProduct.getPrice().longValue()).isEqualTo(changedPrice.longValue()); - } - - @TestGlueOperation("{} 가격 변경에 실패한다") - public void changePrice_result_fail(String name) { - Product product = getAsType(name, Product.class); - Product savedProduct = productRepository.findById(product.getId()).orElseThrow(); - - assertThat(savedProduct.getPrice()).isNotEqualTo(product.getPrice()); - } - - @TestGlueOperation("존재하지 않는 상품 가격 변경에 실패한다") - public void changePrice_no_exist_fail() { - - } - - private BigDecimal toBigDecimal(String price) { - try { - return BigDecimal.valueOf(Long.parseLong(price)); - } catch (NumberFormatException e) { - return null; - } - } -} diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java index 48debf86a..4217cc3fc 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueInitializer.java @@ -1,7 +1,7 @@ package kitchenpos.util.testglue; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Map; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -54,13 +54,18 @@ private void setTestGlueOperation(Object bean, TestGlueOperationContext testGlue testGlueOperationContext.put(description, parameters -> { try { method.invoke(bean, parameters); - } catch (IllegalAccessException | InvocationTargetException e) { + } catch (Exception e) { Throwable cause = e.getCause(); if (cause instanceof AssertionError) { throw (AssertionError) cause; } - throw new RuntimeException(e); + throw new RuntimeException(String.format( + "[메서드 실행 실패]\nmethod name : %s\ndescription : %s\nparameters : %s", + method.getName(), + description, + Arrays.toString(parameters) + ), e); } }); } diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java b/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java index bce61df95..03ff1d333 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java @@ -1,5 +1,8 @@ package kitchenpos.util.testglue; +import java.util.function.Supplier; +import kitchenpos.util.testglue.test.TestGlueResponse; + public class TestGlueSupport implements TestGlueContextAware { private TestGlueValueContext testGlueValueContext; @@ -16,4 +19,21 @@ public T getAsType(String key, Class type) { public void testGlueContext(TestGlueValueContext testGlueValueContext) { this.testGlueValueContext = testGlueValueContext; } + + public TestGlueResponse createResponse(Runnable runnable) { + try { + return TestGlueResponse.ok(new Object()); + } catch (Exception e) { + return TestGlueResponse.exception(e); + } + } + + public TestGlueResponse createResponse(Supplier supplier) { + try { + T response = supplier.get(); + return TestGlueResponse.ok(response); + } catch (Exception e) { + return TestGlueResponse.exception(e); + } + } } diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java b/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java index 69b0b71f2..4bdd3746b 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java @@ -18,7 +18,7 @@ public void put(String key, Object value) { public T getAsType(String key, Class type) { Object o = storage.get(key); if (o == null) { - throw new IllegalArgumentException(String.format("Cannot found key : %s", key)); + return null; } return type.cast(o); diff --git a/src/test/java/kitchenpos/util/testglue/test/TestGlueResponse.java b/src/test/java/kitchenpos/util/testglue/test/TestGlueResponse.java new file mode 100644 index 000000000..c0f299e7a --- /dev/null +++ b/src/test/java/kitchenpos/util/testglue/test/TestGlueResponse.java @@ -0,0 +1,36 @@ +package kitchenpos.util.testglue.test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestGlueResponse { + + private final Exception e; + private final T data; + + private TestGlueResponse(Exception e, T data) { + this.e = e; + this.data = data; + } + + public static TestGlueResponse ok(D data) { + return new TestGlueResponse(null, data); + } + + public static TestGlueResponse exception(Exception e) { + return new TestGlueResponse<>(e, null); + } + + public boolean isOk() { + return data != null; + } + + public T getData() { + assertThat(isOk()).isTrue(); + return data; + } + + public Exception getException() { + assertThat(isOk()).isFalse(); + return e; + } +} From d5b58174cbacb47b463882108a142d367e6eacb7 Mon Sep 17 00:00:00 2001 From: hand Date: Tue, 20 Sep 2022 21:03:57 +0900 Subject: [PATCH 18/21] =?UTF-8?q?test(kitchenpos):=20menu=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++++---- .../application/MenuServiceTest.java | 40 ++++++++++++++- .../application/OrderServiceTest.java | 32 ++++++++++++ .../ProductServiceTest_changePrice.java | 17 ++++--- .../menu/MenuTestGlueConfiguration.java | 51 ++++++++++++++++++- .../product/ProductTestGlueConfiguration.java | 10 ++-- 6 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/test/java/kitchenpos/application/OrderServiceTest.java diff --git a/README.md b/README.md index a7a433a12..c43a9bbf2 100644 --- a/README.md +++ b/README.md @@ -28,21 +28,21 @@ docker compose -p kitchenpos up -d - [x] 메뉴 이름에는 욕설이 포함될 수 없다. - 가격 변경 -- [ ] 가격은 비어있거나 음수일 수 없다. -- [ ] 가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다. -- [ ] 변경하고자 하는 가격이 현재 가격과 같아선 안된다. +- [x] 가격은 비어있거나 음수일 수 없다. +- [x] 가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다. +- [x] 변경하고자 하는 가격이 현재 가격과 같아선 안된다. - 전시 -- [ ] 메뉴는 반드시 존재해야 한다. -- [ ] 메뉴가 가지고 있는 각 메뉴 상품의 가격(수량 * 상품 가격)이 메뉴의 가격보다 작아야한다. //조건이 이상한데?, 생성 조건이랑 다름. +- [x] 메뉴는 반드시 존재해야 한다. +- [x] 메뉴가 가지고 있는 각 메뉴 상품의 가격(수량 * 상품 가격)이 메뉴의 가격보다 작아야한다. //조건이 이상한데?, 생성 조건이랑 다름. - 미전시 -- [ ] 메뉴는 반드시 존재해야 한다. +- [x] 메뉴는 반드시 존재해야 한다. ### 메뉴 상품 - 메뉴 상품은 메뉴에 포함된 각 상품의 수량를 관리한다. -- [ ] 메뉴 상품은 언제나 상품을 갖는다. (not null) -- [ ] 메뉴에 포함된 각 상품 수량이 음수일 수는 없다. +- [x] 메뉴 상품은 언제나 상품을 갖는다. (not null) +- [x] 메뉴에 포함된 각 상품 수량이 음수일 수는 없다. ### 상품 생성 @@ -52,8 +52,8 @@ docker compose -p kitchenpos up -d 가격 변경 - [x] 가격은 비어있거나 0보다 작아서는 안된다. - [x] 상품은 존재해야 한다. -- [ ] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.) - - [ ] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다. +- [x] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.) + - [x] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다. ### 주문메뉴정보 - 주문메뉴정보는 주문에 포함된 각 메뉴의 수량을 관리한다. diff --git a/src/test/java/kitchenpos/application/MenuServiceTest.java b/src/test/java/kitchenpos/application/MenuServiceTest.java index 0ea407394..d0f1d0c9b 100644 --- a/src/test/java/kitchenpos/application/MenuServiceTest.java +++ b/src/test/java/kitchenpos/application/MenuServiceTest.java @@ -146,14 +146,52 @@ void changePrice_exist_menu() { @DisplayName("변경하고자 하는 가격이 현재 가격과 같아선 안된다.") @Test void changePrice() { - + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'추천메뉴' 메뉴 가격을 '-10000' 로 변경하면") + .then("'추천메뉴' 메뉴 가격 변경에 실패한다") + .assertStart(); } + @DisplayName("상품을 전시상태로 변경한다.") @Test void display() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'추천메뉴' 메뉴를 전시상태로 변경하면") + .then("'추천메뉴' 메뉴가 전시상태로 변경된다") + .assertStart(); } + @DisplayName("상품을 전시상태로 변경에 실패한다.") + @Test + void display_fail() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'추천메뉴' 메뉴를 전시상태로 변경하면") + .then("'추천메뉴' 메뉴가 전시상태로 변경된다") + .assertStart(); + } + + @DisplayName("상품을 미전시상태로 변경한다.") @Test void hide() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'추천메뉴' 메뉴를 미전시상태로 변경하면") + .then("'추천메뉴' 메뉴가 미전시상태로 변경된다") + .assertStart(); } } diff --git a/src/test/java/kitchenpos/application/OrderServiceTest.java b/src/test/java/kitchenpos/application/OrderServiceTest.java new file mode 100644 index 000000000..1efbb3771 --- /dev/null +++ b/src/test/java/kitchenpos/application/OrderServiceTest.java @@ -0,0 +1,32 @@ +package kitchenpos.application; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class OrderServiceTest { + + @Test + void create() { + } + + @Test + void accept() { + } + + @Test + void serve() { + } + + @Test + void startDelivery() { + } + + @Test + void completeDelivery() { + } + + @Test + void complete() { + } +} diff --git a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java index b8372efb4..0450eace9 100644 --- a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java +++ b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java @@ -63,15 +63,16 @@ void changePrice_no_exist() { .assertStart(); } - @DisplayName("상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.") - @Test - void changePrice_menu_constraint() { - // todo 메뉴 테스트 작성 후 - } - @DisplayName("상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다. 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다.") @Test - void changePrice_menu_constraint_no_display() { - // todo 메뉴 테스트 작성 후 + void changePrice_menu_constraint() { + testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고") + .when("'상품1' 상품 가격을 '1000' 으로 변경하면") + .then("'추천메뉴' 메뉴가 미전시상태로 변경된다") + .assertStart(); } } diff --git a/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java index ee7a974e9..6af9e970d 100644 --- a/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java @@ -1,6 +1,8 @@ package kitchenpos.testglue.menu; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.jupiter.api.Assertions.assertAll; import java.math.BigDecimal; import java.util.List; @@ -87,8 +89,17 @@ public void create_fail(String name) { assertThat(response.isOk()).isFalse(); } + @TestGlueOperation("{} 메뉴 가격을 {} 로 변경하고") + public void changePrice_exist_menu_given(String name, String price) { + changePrice_exist_menu_when(name, price); + TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + Menu menu = changePriceResponse.getData(); + + put(name, menu); + } + @TestGlueOperation("{} 메뉴 가격을 {} 로 변경하면") - public void changePrice_exist_menu(String name, String price) { + public void changePrice_exist_menu_when(String name, String price) { put("changePrice", toLong(price)); Menu menu = getAsType(name, Menu.class); @@ -106,6 +117,20 @@ public void changePrice_not_exist_menu(String price) { put("changePriceResponse", response); } + @TestGlueOperation("{} 메뉴를 전시상태로 변경하면") + public void changeDisplay_true(String name) { + Menu menu = getAsType(name, Menu.class); + TestGlueResponse response = createResponse(() -> menuService.display(menu.getId())); + put("response", response); + } + + @TestGlueOperation("{} 메뉴를 미전시상태로 변경하면") + public void changeDisplay_false(String name) { + Menu menu = getAsType(name, Menu.class); + TestGlueResponse response = createResponse(() -> menuService.hide(menu.getId())); + put("response", response); + } + @TestGlueOperation("{} 메뉴 가격 변경에 실패한다") public void changePrice(String name) { TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); @@ -124,6 +149,30 @@ public void notExistMenu_changePrice() { assertThat(changePriceResponse.isOk()).isFalse(); } + @TestGlueOperation("{} 메뉴가 전시상태로 변경된다") + public void changeDisplay_true_response(String name) { + TestGlueResponse changePriceResponse = getAsType("response", TestGlueResponse.class); + Menu menu = menuRepository.findById(getAsType(name, Menu.class).getId()).orElseThrow(); + + assertAll( + () -> assertThat(changePriceResponse.isOk()).isTrue(), + () -> assertThat(menu.isDisplayed()).isTrue() + ); + + } + + @TestGlueOperation("{} 메뉴가 미전시상태로 변경된다") + public void changeDisplay_false_response(String name) { + TestGlueResponse changePriceResponse = getAsType("response", TestGlueResponse.class); + Menu menu = menuRepository.findById(getAsType(name, Menu.class).getId()).orElseThrow(); + + assertAll( + () -> assertThat(changePriceResponse.isOk()).isTrue(), + () -> assertThat(menu.isDisplayed()).isFalse() + ); + + } + private Long toLong(String price) { try { return Long.parseLong(price); diff --git a/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java index fa94afff4..9ecd96477 100644 --- a/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/product/ProductTestGlueConfiguration.java @@ -73,7 +73,7 @@ public void changePrice(String name, String price) { put("changedPrice", bigDecimalPrice); TestGlueResponse response = createResponse(() -> productService.changePrice(product.getId(), product)); - put("changePriceResponse", response); + put("response", response); } @TestGlueOperation("존재하지 않는 상품 상품 가격을 {} 으로 변경하면") @@ -82,12 +82,12 @@ public void notExistProduct_changePrice(String price) { product.setPrice(toBigDecimal(price)); TestGlueResponse response = createResponse(() -> productService.changePrice(UUID.randomUUID(), product)); - put("changePriceResponse", response); + put("response", response); } @TestGlueOperation("{} 상품 가격은 변경된다") public void changePrice_result(String name) { - TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + TestGlueResponse changePriceResponse = getAsType("response", TestGlueResponse.class); assertThat(changePriceResponse.isOk()).isTrue(); Product product = getAsType(name, Product.class); @@ -99,7 +99,7 @@ public void changePrice_result(String name) { @TestGlueOperation("{} 상품 가격 변경에 실패한다") public void changePrice_result_fail(String name) { - TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + TestGlueResponse changePriceResponse = getAsType("response", TestGlueResponse.class); assertThat(changePriceResponse.isOk()).isFalse(); Product product = getAsType(name, Product.class); @@ -110,7 +110,7 @@ public void changePrice_result_fail(String name) { @TestGlueOperation("존재하지 않는 상품 상품 가격 변경에 실패한다") public void notExistProduct_changePrice_result() { - TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); + TestGlueResponse changePriceResponse = getAsType("response", TestGlueResponse.class); assertThat(changePriceResponse.isOk()).isFalse(); } From 7ab55fd98fc7bf3525a0fc31cda6fd39838a5d64 Mon Sep 17 00:00:00 2001 From: hand Date: Mon, 3 Oct 2022 14:33:36 +0900 Subject: [PATCH 19/21] =?UTF-8?q?test(kitchenpos):=20orderTable=20test=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +-- .../application/OrderTableServiceTest.java | 70 +++++++++++ .../application/fixture/OrderMother.java | 49 ++++++++ .../application/fixture/OrderTableMother.java | 13 ++ .../java/kitchenpos/domain/OrderTypeTest.java | 22 ++++ .../OrderTableTestGlueConfiguration.java | 115 ++++++++++++++++++ 6 files changed, 276 insertions(+), 7 deletions(-) create mode 100644 src/test/java/kitchenpos/application/OrderTableServiceTest.java create mode 100644 src/test/java/kitchenpos/application/fixture/OrderMother.java create mode 100644 src/test/java/kitchenpos/application/fixture/OrderTableMother.java create mode 100644 src/test/java/kitchenpos/domain/OrderTypeTest.java create mode 100644 src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java diff --git a/README.md b/README.md index c43a9bbf2..4eec96614 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ docker compose -p kitchenpos up -d 주문의 상태 변화 WAITING ``` -- [ ] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN) +- [x] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN) - [ ] 타입은 비어있을 수 없다. - [ ] 주문은 여러 주문메뉴정보를 가질 수 있다. - [ ] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다. @@ -145,11 +145,11 @@ SERVED -> COMPLETED ## 주문 테이블 생성 -- [ ] 테이블 이름은 비어있을 수 없다. +- [x] 테이블 이름은 비어있을 수 없다. 주문 테이블 sit -- [ ] 주문 테이블은 존재해야 한다. -- [ ] 주문 테이블이 occupied상태가 된다. +- [x] 주문 테이블은 존재해야 한다. +- [x] 주문 테이블이 occupied상태가 된다. 주문 테이블 clear - [ ] 주문 테이블은 존재해야 한다. @@ -157,9 +157,9 @@ SERVED -> COMPLETED - [ ] 주문 테이블은 초기화 된다. 주문 테이블 changeNumberOfGuest -- [ ] 손님 수는 음수일 수 없다. -- [ ] 주문 테이블은 존재해야 한다. -- [ ] 주문 테이블은 occupied상태여서는 안된다. +- [x] 손님 수는 음수일 수 없다. +- [x] 주문 테이블은 존재해야 한다. +- [x] 주문 테이블은 occupied상태여서는 안된다. ## 용어 사전 diff --git a/src/test/java/kitchenpos/application/OrderTableServiceTest.java b/src/test/java/kitchenpos/application/OrderTableServiceTest.java new file mode 100644 index 000000000..d94eaee67 --- /dev/null +++ b/src/test/java/kitchenpos/application/OrderTableServiceTest.java @@ -0,0 +1,70 @@ +package kitchenpos.application; + +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@EnableTestGlue +@SpringBootTest +class OrderTableServiceTest { + + @Autowired + private TestGlue testGlue; + + @DisplayName("주문 테이블을 생성한다.") + @Test + void create() { + testGlue.builder() + .given("'테이블1' 주문 테이블을 생성하면") + .then("'테이블1' 주문 테이블이 생성된다") + .assertStart(); + } + + @DisplayName("주문 테이블 이름은 비어있을 수 없다.") + @Test + void createWithEmptyName() { + testGlue.builder() + .given("'' 주문 테이블을 생성하면") + .then("주문 테이블 생성에 실패한다") + .assertStart(); + } + + @DisplayName("주문 테이블에 손님이 앉으면 주문 테이블이 occupied상태가 된다.") + @Test + void sit() { + testGlue.builder() + .given("'테이블1' 주문 테이블을 생성하고") + .when("'테이블1' 주문 테이블에 손님이 앉으면") + .then("'테이블1' 주문 테이블이 occupied상태가 된다.") + .assertStart(); + } + + @Test + void clear() { + //todo 주문 로직이 구현되고 할 것. + } + + @DisplayName("주문 테이블 손님의 수를 변경할 수 있다.") + @Test + void changeNumberOfGuests() { + testGlue.builder() + .given("'테이블1' 주문 테이블을 생성하고") + .given("'테이블1' 주문 테이블에 손님이 앉고") + .when("손님의 수를 '4' 로 변경하면") + .then("'테이블1' 의 손님의 수가 '4'로 변경된다") + .assertStart(); + } + + @DisplayName("occupied 상태가 아니라면 주문 테이블 손님의 수를 변경할 수 있다.") + @Test + void changeNumberOfGuests_notOccupied() { + testGlue.builder() + .given("'테이블1' 주문 테이블을 생성하고") + .when("손님의 수를 '4' 로 변경하면") + .then("주문 테이블 변경에 실패한다") + .assertStart(); + } +} diff --git a/src/test/java/kitchenpos/application/fixture/OrderMother.java b/src/test/java/kitchenpos/application/fixture/OrderMother.java new file mode 100644 index 000000000..7fbc8f154 --- /dev/null +++ b/src/test/java/kitchenpos/application/fixture/OrderMother.java @@ -0,0 +1,49 @@ +package kitchenpos.application.fixture; + +import static kitchenpos.domain.OrderType.DELIVERY; +import static kitchenpos.domain.OrderType.EAT_IN; +import static kitchenpos.domain.OrderType.TAKEOUT; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import kitchenpos.domain.Order; +import kitchenpos.domain.OrderLineItem; +import kitchenpos.domain.OrderType; + +public class OrderMother { + + private static Map creators = new HashMap<>(); + + static { + creators.put("배달주문", ((orderLineItems, orderTableId) -> 주문_request(DELIVERY, orderLineItems, "", orderTableId))); + creators.put("홀주문", ((orderLineItems, orderTableId) -> 주문_request(EAT_IN, orderLineItems, "", orderTableId))); + creators.put("포장주문", ((orderLineItems, orderTableId) -> 주문_request(TAKEOUT, orderLineItems, "", orderTableId))); + } + + public static CreateOrder findCreatorByName(String name) { + return creators.get(name); + } + + private static Order 주문_request( + OrderType orderType, + List orderLineItems, + String deliveryAddress, + UUID orderTableId + ) { + Order order = new Order(); + order.setId(UUID.randomUUID()); + order.setType(orderType); + order.setOrderLineItems(orderLineItems); + order.setDeliveryAddress(deliveryAddress); + order.setOrderTableId(orderTableId); + + return order; + } + + public interface CreateOrder { + + Order create(List orderLineItems, UUID orderTableId); + } +} diff --git a/src/test/java/kitchenpos/application/fixture/OrderTableMother.java b/src/test/java/kitchenpos/application/fixture/OrderTableMother.java new file mode 100644 index 000000000..060043929 --- /dev/null +++ b/src/test/java/kitchenpos/application/fixture/OrderTableMother.java @@ -0,0 +1,13 @@ +package kitchenpos.application.fixture; + +import kitchenpos.domain.OrderTable; + +public class OrderTableMother { + + public static OrderTable create(String name) { + OrderTable orderTable = new OrderTable(); + orderTable.setName(name); + + return orderTable; + } +} diff --git a/src/test/java/kitchenpos/domain/OrderTypeTest.java b/src/test/java/kitchenpos/domain/OrderTypeTest.java new file mode 100644 index 000000000..d8dd15c63 --- /dev/null +++ b/src/test/java/kitchenpos/domain/OrderTypeTest.java @@ -0,0 +1,22 @@ +package kitchenpos.domain; + +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class OrderTypeTest { + + @DisplayName("주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN)") + @Test + void values() { + List names = Arrays.stream(OrderType.values()) + .map(Enum::name) + .collect(toList()); + + assertThat(names).containsExactlyInAnyOrder("DELIVERY", "TAKEOUT", "EAT_IN"); + } +} diff --git a/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java new file mode 100644 index 000000000..442ddb972 --- /dev/null +++ b/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java @@ -0,0 +1,115 @@ +package kitchenpos.testglue.ordertable; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.UUID; +import javax.persistence.EntityNotFoundException; +import kitchenpos.application.OrderTableService; +import kitchenpos.application.fixture.OrderTableMother; +import kitchenpos.domain.OrderTable; +import kitchenpos.domain.OrderTableRepository; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueSupport; +import kitchenpos.util.testglue.test.TestGlueResponse; + +@TestGlueConfiguration +public class OrderTableTestGlueConfiguration extends TestGlueSupport { + + private final OrderTableService orderTableService; + private final OrderTableRepository orderTableRepository; + + public OrderTableTestGlueConfiguration(OrderTableService orderTableService, OrderTableRepository orderTableRepository) { + this.orderTableService = orderTableService; + this.orderTableRepository = orderTableRepository; + } + + @TestGlueOperation("{} 주문 테이블을 생성하면") + public void createOrderTable1(String name) { + OrderTable orderTable = OrderTableMother.create(name); + + TestGlueResponse response = createResponse(() -> orderTableService.create(orderTable)); + + put("orderTableResponse", response); + } + + @TestGlueOperation("{} 주문 테이블을 생성하고") + public void createOrderTable2(String name) { + createOrderTable1(name); + } + + @TestGlueOperation("{} 주문 테이블이 생성된다") + public void createOrderTableResponse_success(String name) { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isTrue(); + + UUID id = response.getData().getId(); + assertThat(orderTableRepository.findById(id)).isNotEmpty(); + } + + @TestGlueOperation("주문 테이블 생성에 실패한다") + public void createOrderTableResponse_fail() { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isFalse(); + } + + @TestGlueOperation("주문 테이블 변경에 실패한다") + public void changeOrderTableResponse_fail() { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isFalse(); + } + + @TestGlueOperation("{} 주문 테이블에 손님이 앉으면") + public void sitOrderTable1(String name) { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + UUID id = response.getData().getId(); + + put("orderTableResponse", createResponse(() -> orderTableService.sit(id))); + } + + @TestGlueOperation("{} 주문 테이블에 손님이 앉고") + public void sitOrderTable2(String name) { + sitOrderTable1(name); + } + + @TestGlueOperation("{} 주문 테이블이 occupied상태가 된다.") + public void sitOrderTableResponse(String name) { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + UUID id = response.getData().getId(); + + OrderTable orderTable = orderTableRepository.findById(id).orElseThrow(EntityNotFoundException::new); + + assertThat(orderTable.isOccupied()).isTrue(); + } + + @TestGlueOperation("손님의 수를 {} 로 변경하면") + public void changeNumberOfGuests(String number) { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + UUID id = response.getData().getId(); + + OrderTable orderTableDto = new OrderTable(); + orderTableDto.setNumberOfGuests(Integer.parseInt(number)); + + put( + "orderTableResponse", + createResponse(() -> orderTableService.changeNumberOfGuests(id, orderTableDto)) + ); + } + + @TestGlueOperation("{} 의 손님의 수가 {}로 변경된다") + public void changeNumberOfGuestsResponse(String name, String number) { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + UUID id = response.getData().getId(); + + OrderTable orderTable = orderTableRepository.findById(id).orElseThrow(EntityNotFoundException::new); + + assertThat(orderTable.getNumberOfGuests()).isEqualTo(Integer.parseInt(number)); + } +} From 0859bd6231edd2263480d6231462f62be8f4b0cd Mon Sep 17 00:00:00 2001 From: hand Date: Mon, 3 Oct 2022 19:56:45 +0900 Subject: [PATCH 20/21] =?UTF-8?q?test(kitchenpos):=20order=20test=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 78 ++--- .../application/OrderServiceTest.java | 304 +++++++++++++++++- .../application/OrderTableServiceTest.java | 4 +- .../fixture/OrderLineItemMother.java | 18 ++ .../application/fixture/OrderMother.java | 7 +- .../KitchenridersClientConfiguration.java | 34 ++ .../menu/MenuTestGlueConfiguration.java | 16 +- .../order/OrderTestGlueConfiguration.java | 246 ++++++++++++++ .../OrderTableTestGlueConfiguration.java | 21 +- 9 files changed, 671 insertions(+), 57 deletions(-) create mode 100644 src/test/java/kitchenpos/application/fixture/OrderLineItemMother.java create mode 100644 src/test/java/kitchenpos/configuration/KitchenridersClientConfiguration.java create mode 100644 src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java diff --git a/README.md b/README.md index 4eec96614..5f89a8056 100644 --- a/README.md +++ b/README.md @@ -57,11 +57,11 @@ docker compose -p kitchenpos up -d ### 주문메뉴정보 - 주문메뉴정보는 주문에 포함된 각 메뉴의 수량을 관리한다. -- [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). -- [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다. -- [ ] 홀이 아닐경우, 음수를 허용하지 않는다. -- [ ] 모든 메뉴는 전시중이어야 한다. -- [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. +- [x] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). +- [x] 홀에서 먹을 경우, 수량은 음수를 허용한다. +- [x] 홀이 아닐경우, 음수를 허용하지 않는다. +- [x] 모든 메뉴는 전시중이어야 한다. +- [x] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. ### 주문 생성 @@ -70,40 +70,40 @@ docker compose -p kitchenpos up -d WAITING ``` - [x] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN) -- [ ] 타입은 비어있을 수 없다. -- [ ] 주문은 여러 주문메뉴정보를 가질 수 있다. -- [ ] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다. -- [ ] 주문에 포함된 주문메뉴정보는, 주문메뉴정보의 제약조건을 모두 만족해야 한다. - - [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). - - [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다. - - [ ] 홀이 아닐경우, 음수를 허용하지 않는다. - - [ ] 모든 메뉴는 전시중이어야 한다. - - [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. -- [ ] 주문의 초기 상태는 WAITING이다. -- [ ] 주문의 타입이 DEVIVERY라면, 주소를 필수로 입력받는다. -- [ ] 주소는 널이거나 비어있지 않다. -- [ ] 주문의 타입이 EAT_IN이라면, 주문 테이블을 필수로 입력 받는다. -- [ ] 주문 테이블의 상태는 occupied상태가 아니어야 한다. -- [ ] 주문 테이블은 존재해야 한다. +- [x] 타입은 비어있을 수 없다. +- [x] 주문은 여러 주문메뉴정보를 가질 수 있다. +- [x] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다. +- [x] 주문에 포함된 주문메뉴정보는, 주문메뉴정보의 제약조건을 모두 만족해야 한다. + - [x] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨). + - [x] 홀에서 먹을 경우, 수량은 음수를 허용한다. + - [x] 홀이 아닐경우, 음수를 허용하지 않는다. + - [x] 모든 메뉴는 전시중이어야 한다. + - [x] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다. +- [x] 주문의 초기 상태는 WAITING이다. +- [x] 주문의 타입이 DEVIVERY라면, 주소를 필수로 입력받는다. +- [x] 주소는 널이거나 비어있지 않다. +- [x] 주문의 타입이 EAT_IN이라면, 주문 테이블을 필수로 입력 받는다. +- [x] 주문 테이블의 상태는 occupied상태여야 한다. +- [x] 주문 테이블은 존재해야 한다. 주문 accept ``` 주문의 상태 변화 WAITING -> ACCEPTED ``` -- [ ] 주문은 존재해야 한다. -- [ ] 주문의 상태는 WAITING 상태여야 한다. -- [ ] 주문 타입이 DELIVER라면, 라이더 시스템으로 배달 요청을 전송한다. -- [ ] 주문 상태를 ACCEPTED 로 변경된다.. +- [x] 주문은 존재해야 한다. +- [x] 주문의 상태는 WAITING 상태여야 한다. +- [x] 주문 타입이 DELIVER라면, 라이더 시스템으로 배달 요청을 전송한다. +- [x] 주문 상태를 ACCEPTED 로 변경된다.. 주문 serve ``` 주문의 상태 변화 ACCEPTED -> SERVED ``` -- [ ] 주문은 존재해야 한다. -- [ ] 주문 상태가 ACCEPTED 상태여야 한다. -- [ ] 주문 상태는 SERVED 로 변경된다. +- [x] 주문은 존재해야 한다. +- [x] 주문 상태가 ACCEPTED 상태여야 한다. +- [x] 주문 상태는 SERVED 로 변경된다. 주문 startDelivery ``` @@ -113,19 +113,19 @@ DELIVERY 타입. 주문의 상태 변화 SERVED -> DELIVERING ``` -- [ ] 주문은 존재해야 한다. -- [ ] 주문은 DELIVERY 타입이어야 한다. -- [ ] 주문은 SERVED 상태여야 한다. -- [ ] 주문 상태는 DELIVERING 으로 변경된다. +- [x] 주문은 존재해야 한다. +- [x] 주문은 DELIVERY 타입이어야 한다. +- [x] 주문은 SERVED 상태여야 한다. +- [x] 주문 상태는 DELIVERING 으로 변경된다. 주문 completeDelivery ``` 주문의 상태 변화 DELIVERING -> DELIVERED ``` -- [ ] 주문은 존재해야 한다. -- [ ] 주문 상태는 DELIVERING 이어야 한다. -- [ ] 주문 상태는 DELIVERED 로 변경된다. +- [x] 주문은 존재해야 한다. +- [x] 주문 상태는 DELIVERING 이어야 한다. +- [x] 주문 상태는 DELIVERED 로 변경된다. 주문 complete ``` @@ -137,11 +137,11 @@ DELIVERED -> COMPLETED [TAKEOUT, EAT_INT 타입] SERVED -> COMPLETED ``` -- [ ] 주문은 존재해야 한다. -- [ ] 주문이 DELIVERY 타입이면, DELIVERED 상태여야 한다. -- [ ] 주문이 TAKEOUT, EAT_IN 타입이면, SERVED 상태여야 한다. -- [ ] 주문이 EAT_IN 타입이고, 소속된 주문 테이블에 완료되지 않은 다른 주문이 없다면, 주문 테이블을 초기화 한다. -- [ ] 주문은 COMPLETED 상태로 변경된다. +- [x] 주문은 존재해야 한다. +- [x] 주문이 DELIVERY 타입이면, DELIVERED 상태여야 한다. +- [x] 주문이 TAKEOUT, EAT_IN 타입이면, SERVED 상태여야 한다. +- [x] 주문이 EAT_IN 타입이고, 소속된 주문 테이블에 완료되지 않은 다른 주문이 없다면, 주문 테이블을 초기화 한다. +- [x] 주문은 COMPLETED 상태로 변경된다. ## 주문 테이블 생성 diff --git a/src/test/java/kitchenpos/application/OrderServiceTest.java b/src/test/java/kitchenpos/application/OrderServiceTest.java index 1efbb3771..6f35d1052 100644 --- a/src/test/java/kitchenpos/application/OrderServiceTest.java +++ b/src/test/java/kitchenpos/application/OrderServiceTest.java @@ -1,32 +1,330 @@ package kitchenpos.application; -import static org.junit.jupiter.api.Assertions.*; - +import kitchenpos.util.testglue.EnableTestGlue; +import kitchenpos.util.testglue.TestGlue; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +@SpringBootTest +@EnableTestGlue class OrderServiceTest { + @Autowired + private TestGlue testGlue; + + @DisplayName("주문을 생성한다.") @Test void create() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문이 생성된다") + .assertStart();; + } + + @DisplayName("주문이 주문메뉴정보를 가지지 않으면 생성에 실패한다.") + @Test + void create_noOrderLineItem() { + 추천_메뉴를_생성하고() + .when("'비어있는' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); } + @DisplayName("주문메뉴정보가 존재하지 않는 메뉴를 가지면 생성에 실패한다.") + @Test + void create_orderLineItemValidation_noExistMenu() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴를 삭제하고") + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("수량은 음수가 될 수 없다.") + @Test + void create_orderLineItemValidation_minusQuantityNotInHole() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '-1' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("홀 주문은 수량이 음수가 될 수 있다.") + @Test + void create_orderLineItemValidation_minusQuantityInHole() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '-1' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'테이블1' 주문 테이블을 생성하고") + .given("'테이블1' 주문 테이블에 손님이 앉고") + .when("'테이블1' 주문 테이블과 '추천메뉴주문정보' 주문메뉴 정보로 '홀주문' 주문을 생성하면") + .then("주문이 생성된다") + .assertStart(); + } + + @DisplayName("모든 메뉴는 전시중이어야 한다") + @Test + void create_orderLineItemValidation_allMenuDisplayed() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'추천메뉴' 메뉴를 미전시상태로 변경하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다") + @Test + void create_orderLineItemValidation_menuAndOrderLineItemPriceMustEqual() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'추천메뉴주문정보' 주문메뉴정보를 가격을 '999999'로 변경하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("주문의 초기 상태는 WAITING이다.") + @Test + void create_initStatusIsWaiting() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하면") + .then("주문의 상태는 'WAITING' 이다") + .assertStart(); + } + + @DisplayName("주문의 타입이 DELIVERY 라면, 주소를 필수로 입력받는다.") + @Test + void create_ifDeliveryTypeAddressIsNecessary() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '주소가 없는 배달주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("주문의 타입이 EAT_IN이라면, 주문 테이블을 필수로 입력 받는다.") + @Test + void create_ifEat_inTypeOrderTableNecessary() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '홀주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("주문 테이블의 상태는 occupied상태여야 한다.") + @Test + void create_orderTableStatusMustBeOccupied() { + 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '-1' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'테이블1' 주문 테이블을 생성하고") + .when("'테이블1' 주문 테이블과 '추천메뉴주문정보' 주문메뉴 정보로 '홀주문' 주문을 생성하면") + .then("주문이 실패한다") + .assertStart(); + } + + @DisplayName("주문을 수락한다") @Test void accept() { + 배달_주문을_생성하고() + .when("'배달주문' 주문을 수락하면") + .then("주문의 상태는 'ACCEPTED' 이다") + .assertStart(); } + @DisplayName("주문을 수락하기 위해서는 주문의 상태는 WAITING 상태여야 한다.") + @Test + void accept_orderStatusMustWaiting() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .when("'배달주문' 주문을 수락하면") + .then("주문 수락에 실패한다") + .assertStart(); + } + + @DisplayName("주문 타입이 DELIVER라면, 라이더 시스템으로 배달 요청을 전송한다.") + @Test + void accept_ifDeliveryTypeSendDeliveryRequestToRiderSystem() { + 배달_주문을_생성하고() + .when("'배달주문' 주문을 수락하면") + .then("배달 요청을 전송한다") + .assertStart(); + } + + @DisplayName("주문 상태는 SERVED 로 변경된다.") @Test void serve() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .when("'배달주문' 주문을 서빙하면") + .then("주문의 상태는 'SERVED' 이다") + .assertStart(); } + @DisplayName("주문 상태가 ACCEPTED 상태여야 한다.") + @Test + void serve_mustAcceptedStatus() { + 배달_주문을_생성하고() + .when("'배달주문' 주문을 서빙하면") + .then("주문 서빙에 실패한다") + .assertStart(); + } + + @DisplayName("주문 상태는 DELIVERING 으로 변경된다") @Test void startDelivery() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .given("'배달주문' 주문을 서빙하고") + .when("'배달주문' 주문 배달을 시작하면") + .then("주문의 상태는 'DELIVERING' 이다") + .assertStart(); + } + + @DisplayName("주문 배송을 시작하기 위해서는 주문은 DELIVERY 타입이어야 한다.") + @Test + void startDelivery_mustDeliveryType() { + 홀_주문을_생성하고() + .given("'홀주문' 주문을 수락하고") + .given("'홀주문' 주문을 서빙하고") + .when("'홀주문' 주문 배달을 시작하면") + .then("주문 배달에 실패한다") + .assertStart(); + } + + @DisplayName("주문 배송을 시작하기 위해서는 주문은 SERVED 상태여야 한다.") + @Test + void startDelivery_mustServedStatus() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .when("'배달주문' 주문 배달을 시작하면") + .then("주문 배달에 실패한다") + .assertStart(); } + @DisplayName("주문이 완료되면 주문 상태는 DELIVERED 로 변경된다.") @Test void completeDelivery() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .given("'배달주문' 주문을 서빙하고") + .given("'배달주문' 주문 배달을 시작하고") + .when("'배달주문' 배달 완료가 되면") + .then("주문의 상태는 'DELIVERED' 이다") + .assertStart(); + } + + @DisplayName("배달주 완료하기 위해서는 주문 상태는 DELIVERING 이어야 한다.") + @Test + void completeDelivery_orderStatusMustDelivering() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .given("'배달주문' 주문을 서빙하고") + .when("'배달주문' 배달 완료가 되면") + .then("배달 완료에 실패한다") + .assertStart(); + } + + @DisplayName("주문을 완료하기 위해 주문이 DELIVERY 타입이면, DELIVERED 상태여야 한다.") + @Test + void complete_DELIVERY() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .given("'배달주문' 주문을 서빙하고") + .given("'배달주문' 주문 배달을 시작하고") + .given("'배달주문' 배달 완료가 되고") + .when("'배달주문' 주문을 종료하면") + .then("주문의 상태는 'COMPLETED' 이다") + .assertStart(); + } + + @DisplayName("주문을 완료하기 위해 주문이 EAT_IN 타입이면, DELIVERED 상태여야 한다.") + @Test + void complete_EAT_IN() { + 홀_주문을_생성하고() + .given("'홀주문' 주문을 수락하고") + .given("'홀주문' 주문을 서빙하고") + .when("'홀주문' 주문을 종료하면") + .then("주문의 상태는 'COMPLETED' 이다") + .assertStart(); + } + + @DisplayName("주문을 완료하기 위해 주문이 TAKEOUT 타입이면, DELIVERED 상태여야 한다.") + @Test + void complete_TAKEOUT() { + 포장_주문을_생성하고() + .given("'포장주문' 주문을 수락하고") + .given("'포장주문' 주문을 서빙하고") + .when("'포장주문' 주문을 종료하면") + .then("주문의 상태는 'COMPLETED' 이다") + .assertStart(); + } + + @DisplayName("주문을 완료하기 위해 주문이 DELIVERY 타입이면, DELIVERED 상태여야 한다. - 실패") + @Test + void complete_DELIVERY_fail() { + 배달_주문을_생성하고() + .given("'배달주문' 주문을 수락하고") + .given("'배달주문' 주문을 서빙하고") + .given("'배달주문' 주문 배달을 시작하고") + .when("'배달주문' 주문을 종료하면") + .then("주문 완료에 실패한다") + .assertStart(); + } + + @DisplayName("주문을 완료하기 위해 주문이 EAT_IN 타입이면, DELIVERED 상태여야 한다. - 실패") + @Test + void complete_EAT_IN_fail() { + 홀_주문을_생성하고() + .given("'홀주문' 주문을 수락하고") + .when("'홀주문' 주문을 종료하면") + .then("주문 완료에 실패한다") + .assertStart(); } + @DisplayName("주문을 완료하기 위해 주문이 TAKEOUT 타입이면, DELIVERED 상태여야 한다. - 실패") @Test - void complete() { + void complete_TAKEOUT_fail() { + 포장_주문을_생성하고() + .given("'포장주문' 주문을 수락하고") + .when("'포장주문' 주문을 종료하면") + .then("주문 완료에 실패한다") + .assertStart(); + } + + private TestGlue.Builder 추천_메뉴를_생성하고() { + return testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고"); + } + + private TestGlue.Builder 홀_주문을_생성하고() { + return 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'테이블1' 주문 테이블을 생성하고") + .given("'테이블1' 주문 테이블에 손님이 앉고") + .when("'테이블1' 주문 테이블과 '추천메뉴주문정보' 주문메뉴 정보로 '홀주문' 주문을 생성하고"); + } + + private TestGlue.Builder 포장_주문을_생성하고() { + return 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'테이블1' 주문 테이블을 생성하고") + .given("'테이블1' 주문 테이블에 손님이 앉고") + .when("'테이블1' 주문 테이블과 '추천메뉴주문정보' 주문메뉴 정보로 '포장주문' 주문을 생성하고"); + } + + private TestGlue.Builder 배달_주문을_생성하고() { + return 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .when("'추천메뉴주문정보' 주문메뉴 정보로 '배달주문' 주문을 생성하고"); } } diff --git a/src/test/java/kitchenpos/application/OrderTableServiceTest.java b/src/test/java/kitchenpos/application/OrderTableServiceTest.java index d94eaee67..7be640be9 100644 --- a/src/test/java/kitchenpos/application/OrderTableServiceTest.java +++ b/src/test/java/kitchenpos/application/OrderTableServiceTest.java @@ -53,7 +53,7 @@ void changeNumberOfGuests() { testGlue.builder() .given("'테이블1' 주문 테이블을 생성하고") .given("'테이블1' 주문 테이블에 손님이 앉고") - .when("손님의 수를 '4' 로 변경하면") + .when("'테이블1' 주문 테이블 손님의 수를 '4' 로 변경하면") .then("'테이블1' 의 손님의 수가 '4'로 변경된다") .assertStart(); } @@ -63,7 +63,7 @@ void changeNumberOfGuests() { void changeNumberOfGuests_notOccupied() { testGlue.builder() .given("'테이블1' 주문 테이블을 생성하고") - .when("손님의 수를 '4' 로 변경하면") + .when("'테이블1' 주문 테이블 손님의 수를 '4' 로 변경하면") .then("주문 테이블 변경에 실패한다") .assertStart(); } diff --git a/src/test/java/kitchenpos/application/fixture/OrderLineItemMother.java b/src/test/java/kitchenpos/application/fixture/OrderLineItemMother.java new file mode 100644 index 000000000..7b8ffc6e0 --- /dev/null +++ b/src/test/java/kitchenpos/application/fixture/OrderLineItemMother.java @@ -0,0 +1,18 @@ +package kitchenpos.application.fixture; + +import java.math.BigDecimal; +import java.util.UUID; +import kitchenpos.domain.OrderLineItem; + +public class OrderLineItemMother { + + public static OrderLineItem create(UUID menuId, BigDecimal menuPrice, int quantity) { + OrderLineItem orderLineItem = new OrderLineItem(); + + orderLineItem.setMenuId(menuId); + orderLineItem.setQuantity(quantity); + orderLineItem.setPrice(menuPrice); + + return orderLineItem; + } +} diff --git a/src/test/java/kitchenpos/application/fixture/OrderMother.java b/src/test/java/kitchenpos/application/fixture/OrderMother.java index 7fbc8f154..b8c4b16d1 100644 --- a/src/test/java/kitchenpos/application/fixture/OrderMother.java +++ b/src/test/java/kitchenpos/application/fixture/OrderMother.java @@ -17,9 +17,10 @@ public class OrderMother { private static Map creators = new HashMap<>(); static { - creators.put("배달주문", ((orderLineItems, orderTableId) -> 주문_request(DELIVERY, orderLineItems, "", orderTableId))); - creators.put("홀주문", ((orderLineItems, orderTableId) -> 주문_request(EAT_IN, orderLineItems, "", orderTableId))); - creators.put("포장주문", ((orderLineItems, orderTableId) -> 주문_request(TAKEOUT, orderLineItems, "", orderTableId))); + creators.put("배달주문", ((orderLineItems, orderTableId) -> 주문_request(DELIVERY, orderLineItems, "a", orderTableId))); + creators.put("주소가 없는 배달주문", ((orderLineItems, orderTableId) -> 주문_request(DELIVERY, orderLineItems, "", orderTableId))); + creators.put("홀주문", ((orderLineItems, orderTableId) -> 주문_request(EAT_IN, orderLineItems, "a", orderTableId))); + creators.put("포장주문", ((orderLineItems, orderTableId) -> 주문_request(TAKEOUT, orderLineItems, "a", orderTableId))); } public static CreateOrder findCreatorByName(String name) { diff --git a/src/test/java/kitchenpos/configuration/KitchenridersClientConfiguration.java b/src/test/java/kitchenpos/configuration/KitchenridersClientConfiguration.java new file mode 100644 index 000000000..dddd45051 --- /dev/null +++ b/src/test/java/kitchenpos/configuration/KitchenridersClientConfiguration.java @@ -0,0 +1,34 @@ +package kitchenpos.configuration; + +import java.math.BigDecimal; +import java.util.UUID; +import kitchenpos.infra.KitchenridersClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.ActiveProfiles; + +@Configuration +@ActiveProfiles("test") +public class KitchenridersClientConfiguration { + + @Bean(name = "fakeKitchenridersClient") + @Primary + public KitchenridersClient kitchenridersClient() { + return new FakeKitchenridersClient(); + } + + public static class FakeKitchenridersClient extends KitchenridersClient { + + private int requestCount; + + @Override + public void requestDelivery(UUID orderId, BigDecimal amount, String deliveryAddress) { + requestCount++; + } + + public int getRequestCount() { + return requestCount; + } + } +} diff --git a/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java index 6af9e970d..f0158d60c 100644 --- a/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/menu/MenuTestGlueConfiguration.java @@ -53,7 +53,6 @@ public void create_data( Menu menuRequest = MenuMother.findCreatorByName(name).create(name, menuGroup, List.of(menuProduct)); put(name, menuRequest); - } @TestGlueOperation("{} 메뉴를 생성하고") @@ -125,12 +124,19 @@ public void changeDisplay_true(String name) { } @TestGlueOperation("{} 메뉴를 미전시상태로 변경하면") - public void changeDisplay_false(String name) { + public void changeDisplay_false1(String name) { Menu menu = getAsType(name, Menu.class); TestGlueResponse response = createResponse(() -> menuService.hide(menu.getId())); put("response", response); } + @TestGlueOperation("{} 메뉴를 미전시상태로 변경하고") + public void changeDisplay_false2(String name) { + Menu menu = getAsType(name, Menu.class); + menuService.hide(menu.getId()); + put(name, menu); + } + @TestGlueOperation("{} 메뉴 가격 변경에 실패한다") public void changePrice(String name) { TestGlueResponse changePriceResponse = getAsType("changePriceResponse", TestGlueResponse.class); @@ -170,7 +176,13 @@ public void changeDisplay_false_response(String name) { () -> assertThat(changePriceResponse.isOk()).isTrue(), () -> assertThat(menu.isDisplayed()).isFalse() ); + } + @TestGlueOperation("{} 메뉴를 삭제하고") + public void deleteMenu(String name) { + // 제거가 어려움으로 UUID를 변경하여 비슷한 효과를 낸다. + Menu menu = getAsType(name, Menu.class); + menu.setId(UUID.randomUUID()); } private Long toLong(String price) { diff --git a/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java new file mode 100644 index 000000000..1adb4b8aa --- /dev/null +++ b/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java @@ -0,0 +1,246 @@ +package kitchenpos.testglue.order; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import kitchenpos.application.OrderService; +import kitchenpos.application.fixture.OrderLineItemMother; +import kitchenpos.application.fixture.OrderMother; +import kitchenpos.configuration.KitchenridersClientConfiguration.FakeKitchenridersClient; +import kitchenpos.domain.Menu; +import kitchenpos.domain.Order; +import kitchenpos.domain.OrderLineItem; +import kitchenpos.domain.OrderRepository; +import kitchenpos.domain.OrderStatus; +import kitchenpos.domain.OrderTable; +import kitchenpos.infra.KitchenridersClient; +import kitchenpos.util.testglue.TestGlueConfiguration; +import kitchenpos.util.testglue.TestGlueOperation; +import kitchenpos.util.testglue.TestGlueSupport; +import kitchenpos.util.testglue.test.TestGlueResponse; + +@TestGlueConfiguration +public class OrderTestGlueConfiguration extends TestGlueSupport { + + private final OrderService orderService; + private final OrderRepository orderRepository; + private final KitchenridersClient kitchenridersClient; + + public OrderTestGlueConfiguration( + OrderService orderService, + OrderRepository orderRepository, + KitchenridersClient kitchenridersClient + ) { + this.orderService = orderService; + this.orderRepository = orderRepository; + this.kitchenridersClient = kitchenridersClient; + } + + @TestGlueOperation("{} 메뉴 {} 개로 {} 주문메뉴정보를 생성하고") + public void createOrderLineItem(String menuName, String quantity, String orderLineItemName) { + Menu menu = getAsType(menuName, Menu.class); + + OrderLineItem orderLineItem = OrderLineItemMother.create(menu.getId(), menu.getPrice(), Integer.parseInt(quantity)); + + List orderLineItems = getAsType(orderLineItemName, List.class); + if (orderLineItems == null) { + put(orderLineItemName, new ArrayList<>()); + } + orderLineItems = getAsType(orderLineItemName, List.class); + + orderLineItems.add(orderLineItem); + } + + @TestGlueOperation("{} 주문메뉴정보를 가격을 {}로 변경하고") + public void createOrderLineItem_setPrice(String orderLineItemName, String price) { + List orderLineItem = getAsType(orderLineItemName, List.class); + orderLineItem.forEach(v -> v.setPrice(BigDecimal.valueOf(Long.parseLong(price)))); + } + + @TestGlueOperation("{} 주문 테이블과 {} 주문메뉴 정보로 {} 주문을 생성하면") + public void createOrderTable(String orderTableName, String orderLineItemsName, String orderName) { + List orderLineItems = getAsType(orderLineItemsName, List.class); + var orderTable = getAsType(orderTableName, OrderTable.class); + + Order order = OrderMother + .findCreatorByName(orderName) + .create(orderLineItems, orderTable.getId()); + + TestGlueResponse response = createResponse(() -> orderService.create(order)); + + put("orderResponse", response); + } + + @TestGlueOperation("{} 주문메뉴 정보로 {} 주문을 생성하면") + public void createOrderTable_noOrderTable(String orderLineItemsName, String orderName) { + createOrderTable(UUID.randomUUID().toString(), orderLineItemsName, orderName); + } + + @TestGlueOperation("{} 주문 테이블과 {} 주문메뉴 정보로 {} 주문을 생성하고") + public void createOrderTable2(String orderTableName, String orderLineItemsName, String orderName) { + List orderLineItems = getAsType(orderLineItemsName, List.class); + var orderTable = getAsType(orderTableName, OrderTable.class); + + Order order = OrderMother + .findCreatorByName(orderName) + .create(orderLineItems, orderTable == null ? null : orderTable.getId()); + + put(orderName, orderService.create(order)); + } + + @TestGlueOperation("{} 주문메뉴 정보로 {} 주문을 생성하고") + public void createOrderTable_noOrderTable2(String orderLineItemsName, String orderName) { + createOrderTable2(UUID.randomUUID().toString(), orderLineItemsName, orderName); + } + + @TestGlueOperation("주문이 생성된다") + public void createOrderResponse() { + TestGlueResponse response = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isTrue(); + + assertThat(orderRepository.findById(response.getData().getId())).isNotEmpty(); + } + + @TestGlueOperation("주문이 실패한다") + public void createOrderResponse_fail() { + TestGlueResponse response = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isFalse(); + } + + @TestGlueOperation("주문의 상태는 {} 이다") + public void orderStatus(String status) { + OrderStatus orderStatus = OrderStatus.valueOf(status); + + TestGlueResponse response = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isTrue(); + assertThat(response.getData().getStatus()).isEqualTo(orderStatus); + } + + @TestGlueOperation("{} 주문을 수락하면") + public void accept(String orderName) { + Order order = getAsType(orderName, Order.class); + + TestGlueResponse response = createResponse(() -> orderService.accept(order.getId())); + + put("orderResponse", response); + } + + @TestGlueOperation("{} 주문을 수락하고") + public void accept2(String orderName) { + Order order = getAsType(orderName, Order.class); + + put(orderName, orderService.accept(order.getId())); + } + + @TestGlueOperation("주문 수락에 실패한다") + public void accept_fail() { + TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(orderResponse.isOk()).isFalse(); + } + + @TestGlueOperation("주문 수락에 실패한다") + public void accept_deliverySystem() { + TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(orderResponse.isOk()).isFalse(); + } + + @TestGlueOperation("배달 요청을 전송한다") + public void accept_requestToRiderSystem() { + FakeKitchenridersClient kitchenridersClient = (FakeKitchenridersClient) this.kitchenridersClient; + + assertThat(kitchenridersClient.getRequestCount() >= 1).isTrue(); + } + + @TestGlueOperation("{} 주문을 서빙하면") + public void serve(String orderName) { + Order order = getAsType(orderName, Order.class); + + TestGlueResponse response = createResponse(() -> orderService.serve(order.getId())); + + put("orderResponse", response); + } + + @TestGlueOperation("{} 주문을 서빙하고") + public void serve2(String orderName) { + Order order = getAsType(orderName, Order.class); + + put(orderName, orderService.serve(order.getId())); + } + + @TestGlueOperation("주문 서빙에 실패한다") + public void serve_fail() { + TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(orderResponse.isOk()).isFalse(); + } + + @TestGlueOperation("{} 주문 배달을 시작하면") + public void startDelivery(String orderName) { + Order order = getAsType(orderName, Order.class); + + TestGlueResponse response = createResponse(() -> orderService.startDelivery(order.getId())); + + put("orderResponse", response); + } + + @TestGlueOperation("{} 주문 배달을 시작하고") + public void startDelivery2(String orderName) { + Order order = getAsType(orderName, Order.class); + + put(orderName, orderService.startDelivery(order.getId())); + } + + @TestGlueOperation("주문 배달에 실패한다") + public void startDelivery_fail() { + TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(orderResponse.isOk()).isFalse(); + } + + @TestGlueOperation("{} 배달 완료가 되면") + public void completeDelivery(String orderName) { + Order order = getAsType(orderName, Order.class); + + TestGlueResponse response = createResponse(() -> orderService.completeDelivery(order.getId())); + + put("orderResponse", response); + } + + @TestGlueOperation("{} 배달 완료가 되고") + public void completeDelivery2(String orderName) { + Order order = getAsType(orderName, Order.class); + + put(orderName, orderService.completeDelivery(order.getId())); + } + + @TestGlueOperation("배달 완료에 실패한다") + public void completeDelivery_fail() { + TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(orderResponse.isOk()).isFalse(); + } + + @TestGlueOperation("{} 주문을 종료하면") + public void complete(String orderName) { + Order order = getAsType(orderName, Order.class); + + TestGlueResponse response = createResponse(() -> orderService.complete(order.getId())); + + put("orderResponse", response); + } + + @TestGlueOperation("주문 완료에 실패한다") + public void complete_fail() { + TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); + + assertThat(orderResponse.isOk()).isFalse(); + } +} diff --git a/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java index 442ddb972..05e7eca3a 100644 --- a/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java @@ -35,7 +35,9 @@ public void createOrderTable1(String name) { @TestGlueOperation("{} 주문 테이블을 생성하고") public void createOrderTable2(String name) { - createOrderTable1(name); + OrderTable orderTable = OrderTableMother.create(name); + + put(name, orderTableService.create(orderTable)); } @TestGlueOperation("{} 주문 테이블이 생성된다") @@ -64,16 +66,19 @@ public void changeOrderTableResponse_fail() { @TestGlueOperation("{} 주문 테이블에 손님이 앉으면") public void sitOrderTable1(String name) { - TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + OrderTable orderTable = getAsType(name, OrderTable.class); - UUID id = response.getData().getId(); + UUID id = orderTable.getId(); put("orderTableResponse", createResponse(() -> orderTableService.sit(id))); } @TestGlueOperation("{} 주문 테이블에 손님이 앉고") public void sitOrderTable2(String name) { - sitOrderTable1(name); + OrderTable orderTable = getAsType(name, OrderTable.class); + UUID id = orderTable.getId(); + + put(name, orderTableService.sit(id)); } @TestGlueOperation("{} 주문 테이블이 occupied상태가 된다.") @@ -87,11 +92,11 @@ public void sitOrderTableResponse(String name) { assertThat(orderTable.isOccupied()).isTrue(); } - @TestGlueOperation("손님의 수를 {} 로 변경하면") - public void changeNumberOfGuests(String number) { - TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + @TestGlueOperation("{} 주문 테이블 손님의 수를 {} 로 변경하면") + public void changeNumberOfGuests(String name, String number) { + OrderTable orderTable = getAsType(name, OrderTable.class); - UUID id = response.getData().getId(); + UUID id = orderTable.getId(); OrderTable orderTableDto = new OrderTable(); orderTableDto.setNumberOfGuests(Integer.parseInt(number)); From ffeb4124b7479f21f41d1b3dd1d006b6a975ac2e Mon Sep 17 00:00:00 2001 From: hand Date: Mon, 3 Oct 2022 20:35:16 +0900 Subject: [PATCH 21/21] =?UTF-8?q?test(kitchenpos):=20order=20table=20clear?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- .../application/MenuGroupServiceTest.java | 3 +- .../application/MenuServiceTest.java | 3 +- .../application/OrderServiceTest.java | 3 +- .../application/OrderTableServiceTest.java | 39 ++++++++++- .../ProductServiceTest_changePrice.java | 3 +- .../ProductServiceTest_create.java | 3 +- .../configuration/DataInitializer.java | 64 +++++++++++++++++++ .../TestGlueContextAwareHelper.java | 22 +++++++ .../configuration/TestIsolationSupport.java | 19 ++++++ .../order/OrderTestGlueConfiguration.java | 9 ++- .../OrderTableTestGlueConfiguration.java | 29 +++++++++ .../util/testglue/TestGlueSupport.java | 6 ++ .../util/testglue/TestGlueValueContext.java | 6 ++ 14 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 src/test/java/kitchenpos/configuration/DataInitializer.java create mode 100644 src/test/java/kitchenpos/configuration/TestGlueContextAwareHelper.java create mode 100644 src/test/java/kitchenpos/configuration/TestIsolationSupport.java diff --git a/README.md b/README.md index 5f89a8056..d62096dac 100644 --- a/README.md +++ b/README.md @@ -152,9 +152,9 @@ SERVED -> COMPLETED - [x] 주문 테이블이 occupied상태가 된다. 주문 테이블 clear -- [ ] 주문 테이블은 존재해야 한다. -- [ ] 주문 테이블에 연관된 주문은 모두 COMPLETED 상태여야 한다. -- [ ] 주문 테이블은 초기화 된다. +- [x] 주문 테이블은 존재해야 한다. +- [x] 주문 테이블에 연관된 주문은 모두 COMPLETED 상태여야 한다. +- [x] 주문 테이블은 초기화 된다. 주문 테이블 changeNumberOfGuest - [x] 손님 수는 음수일 수 없다. diff --git a/src/test/java/kitchenpos/application/MenuGroupServiceTest.java b/src/test/java/kitchenpos/application/MenuGroupServiceTest.java index 0b9c30a14..56f5fde59 100644 --- a/src/test/java/kitchenpos/application/MenuGroupServiceTest.java +++ b/src/test/java/kitchenpos/application/MenuGroupServiceTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.*; +import kitchenpos.configuration.TestIsolationSupport; import kitchenpos.util.testglue.EnableTestGlue; import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; @@ -11,7 +12,7 @@ @EnableTestGlue @SpringBootTest -class MenuGroupServiceTest { +class MenuGroupServiceTest extends TestIsolationSupport { @Autowired private TestGlue testGlue; diff --git a/src/test/java/kitchenpos/application/MenuServiceTest.java b/src/test/java/kitchenpos/application/MenuServiceTest.java index d0f1d0c9b..501754bbd 100644 --- a/src/test/java/kitchenpos/application/MenuServiceTest.java +++ b/src/test/java/kitchenpos/application/MenuServiceTest.java @@ -1,5 +1,6 @@ package kitchenpos.application; +import kitchenpos.configuration.TestIsolationSupport; import kitchenpos.util.testglue.EnableTestGlue; import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; @@ -9,7 +10,7 @@ @SpringBootTest @EnableTestGlue -class MenuServiceTest { +class MenuServiceTest extends TestIsolationSupport { @Autowired private TestGlue testGlue; diff --git a/src/test/java/kitchenpos/application/OrderServiceTest.java b/src/test/java/kitchenpos/application/OrderServiceTest.java index 6f35d1052..3d2be8fc0 100644 --- a/src/test/java/kitchenpos/application/OrderServiceTest.java +++ b/src/test/java/kitchenpos/application/OrderServiceTest.java @@ -1,5 +1,6 @@ package kitchenpos.application; +import kitchenpos.configuration.TestIsolationSupport; import kitchenpos.util.testglue.EnableTestGlue; import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; @@ -9,7 +10,7 @@ @SpringBootTest @EnableTestGlue -class OrderServiceTest { +class OrderServiceTest extends TestIsolationSupport { @Autowired private TestGlue testGlue; diff --git a/src/test/java/kitchenpos/application/OrderTableServiceTest.java b/src/test/java/kitchenpos/application/OrderTableServiceTest.java index 7be640be9..a8cbb83d2 100644 --- a/src/test/java/kitchenpos/application/OrderTableServiceTest.java +++ b/src/test/java/kitchenpos/application/OrderTableServiceTest.java @@ -1,5 +1,6 @@ package kitchenpos.application; +import kitchenpos.configuration.TestIsolationSupport; import kitchenpos.util.testglue.EnableTestGlue; import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; @@ -9,7 +10,7 @@ @EnableTestGlue @SpringBootTest -class OrderTableServiceTest { +class OrderTableServiceTest extends TestIsolationSupport { @Autowired private TestGlue testGlue; @@ -42,9 +43,43 @@ void sit() { .assertStart(); } + @DisplayName("주문 테이블 초기화를 요청하면, 주문 테이블은 초기화 된다.") @Test void clear() { - //todo 주문 로직이 구현되고 할 것. + 홀_주문을_생성하고() + .given("'홀주문' 주문을 수락하고") + .given("'홀주문' 주문을 서빙하고") + .given("'홀주문' 주문을 종료하고") + .when("'테이블1' 주문 테이블을 정리하면") + .then("주문 테이블은 초기화 된다") + .assertStart(); + } + + @DisplayName("주문 테이블에 연관된 주문이 COMPLETED 상태가 아니면, 초기화 할 수 없다.") + @Test + void clea_fail() { + 홀_주문을_생성하고() + .given("'홀주문' 주문을 수락하고") + .given("'홀주문' 주문을 서빙하고") + .when("'테이블1' 주문 테이블을 정리하면") + .then("주문 테이블 초기화에 실패한다") + .assertStart(); + } + + private TestGlue.Builder 추천_메뉴를_생성하고() { + return testGlue.builder() + .given("'추천메뉴그룹' 메뉴 그룹을 생성하고") + .given("'상품1' 상품을 생성하고") + .given("'추천메뉴그룹'에 속하고 '상품1' '3'개를 이용해 '추천메뉴' 메뉴 데이터를 만들고") + .given("'추천메뉴' 메뉴를 생성하고"); + } + + private TestGlue.Builder 홀_주문을_생성하고() { + return 추천_메뉴를_생성하고() + .given("'추천메뉴' 메뉴 '4' 개로 '추천메뉴주문정보' 주문메뉴정보를 생성하고") + .given("'테이블1' 주문 테이블을 생성하고") + .given("'테이블1' 주문 테이블에 손님이 앉고") + .when("'테이블1' 주문 테이블과 '추천메뉴주문정보' 주문메뉴 정보로 '홀주문' 주문을 생성하고"); } @DisplayName("주문 테이블 손님의 수를 변경할 수 있다.") diff --git a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java index 0450eace9..37788c9ee 100644 --- a/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java +++ b/src/test/java/kitchenpos/application/ProductServiceTest_changePrice.java @@ -1,5 +1,6 @@ package kitchenpos.application; +import kitchenpos.configuration.TestIsolationSupport; import kitchenpos.util.testglue.EnableTestGlue; import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; @@ -9,7 +10,7 @@ @EnableTestGlue @SpringBootTest -class ProductServiceTest_changePrice { +class ProductServiceTest_changePrice extends TestIsolationSupport { @Autowired private TestGlue testGlue; diff --git a/src/test/java/kitchenpos/application/ProductServiceTest_create.java b/src/test/java/kitchenpos/application/ProductServiceTest_create.java index c975de385..3ccdedc06 100644 --- a/src/test/java/kitchenpos/application/ProductServiceTest_create.java +++ b/src/test/java/kitchenpos/application/ProductServiceTest_create.java @@ -1,5 +1,6 @@ package kitchenpos.application; +import kitchenpos.configuration.TestIsolationSupport; import kitchenpos.util.testglue.EnableTestGlue; import kitchenpos.util.testglue.TestGlue; import org.junit.jupiter.api.DisplayName; @@ -9,7 +10,7 @@ @EnableTestGlue @SpringBootTest -class ProductServiceTest_create { +class ProductServiceTest_create extends TestIsolationSupport { @Autowired private TestGlue testGlue; diff --git a/src/test/java/kitchenpos/configuration/DataInitializer.java b/src/test/java/kitchenpos/configuration/DataInitializer.java new file mode 100644 index 000000000..c909e63c9 --- /dev/null +++ b/src/test/java/kitchenpos/configuration/DataInitializer.java @@ -0,0 +1,64 @@ +package kitchenpos.configuration; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.EntityManager; +import org.hibernate.Session; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.test.context.ActiveProfiles; + +@Component +@ActiveProfiles("test") +public class DataInitializer implements InitializingBean { + + @Autowired + private EntityManager entityManager; + + private List tableNames; + + @Override + public void afterPropertiesSet() { + entityManager.unwrap(Session.class) + .doWork(this::extractTableNames); + } + + private void extractTableNames(Connection conn) throws SQLException { + List tableNames = new ArrayList<>(); + + ResultSet tables = conn + .getMetaData() + .getTables(conn.getCatalog(), null, "%", new String[]{"TABLE"}); + + while (tables.next()) { + tableNames.add(tables.getString("table_name")); + } + + this.tableNames = tableNames; + } + + public void execute() { + entityManager.unwrap(Session.class) + .doWork(this::cleanUpDatabase); + } + + private void cleanUpDatabase(Connection conn) throws SQLException { + Statement statement = conn.createStatement(); + statement.executeUpdate("SET REFERENTIAL_INTEGRITY FALSE"); + + for (String tableName : tableNames) { + try { + statement.executeUpdate("TRUNCATE TABLE " + tableName); + statement.executeUpdate("ALTER TABLE " + tableName + " ALTER COLUMN id RESTART WITH 1"); + } catch (Exception ignore) { + } + } + + statement.executeUpdate("SET REFERENTIAL_INTEGRITY TRUE"); + } +} diff --git a/src/test/java/kitchenpos/configuration/TestGlueContextAwareHelper.java b/src/test/java/kitchenpos/configuration/TestGlueContextAwareHelper.java new file mode 100644 index 000000000..212a929e1 --- /dev/null +++ b/src/test/java/kitchenpos/configuration/TestGlueContextAwareHelper.java @@ -0,0 +1,22 @@ +package kitchenpos.configuration; + +import kitchenpos.util.testglue.TestGlueContextAware; +import kitchenpos.util.testglue.TestGlueValueContext; +import org.springframework.stereotype.Component; +import org.springframework.test.context.ActiveProfiles; + +@Component +@ActiveProfiles("test") +public class TestGlueContextAwareHelper implements TestGlueContextAware { + + private TestGlueValueContext testGlueValueContext; + + @Override + public void testGlueContext(TestGlueValueContext testGlueValueContext) { + this.testGlueValueContext = testGlueValueContext; + } + + public void clear() { + testGlueValueContext.clear(); + } +} diff --git a/src/test/java/kitchenpos/configuration/TestIsolationSupport.java b/src/test/java/kitchenpos/configuration/TestIsolationSupport.java new file mode 100644 index 000000000..82ebb71f2 --- /dev/null +++ b/src/test/java/kitchenpos/configuration/TestIsolationSupport.java @@ -0,0 +1,19 @@ +package kitchenpos.configuration; + +import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.annotation.Autowired; + +public class TestIsolationSupport { + + @Autowired + private DataInitializer dataInitializer; + + @Autowired + private TestGlueContextAwareHelper testGlueContextAwareHelper; + + @BeforeEach + void setUp() { + dataInitializer.execute(); + testGlueContextAwareHelper.clear(); + } +} diff --git a/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java index 1adb4b8aa..e77b1acc9 100644 --- a/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/order/OrderTestGlueConfiguration.java @@ -67,7 +67,7 @@ public void createOrderTable(String orderTableName, String orderLineItemsName, S Order order = OrderMother .findCreatorByName(orderName) - .create(orderLineItems, orderTable.getId()); + .create(orderLineItems, orderTable == null ? null : orderTable.getId()); TestGlueResponse response = createResponse(() -> orderService.create(order)); @@ -237,6 +237,13 @@ public void complete(String orderName) { put("orderResponse", response); } + @TestGlueOperation("{} 주문을 종료하고") + public void complete2(String orderName) { + Order order = getAsType(orderName, Order.class); + + put(orderName, orderService.complete(order.getId())); + } + @TestGlueOperation("주문 완료에 실패한다") public void complete_fail() { TestGlueResponse orderResponse = getAsType("orderResponse", TestGlueResponse.class); diff --git a/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java b/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java index 05e7eca3a..dbc18f02c 100644 --- a/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java +++ b/src/test/java/kitchenpos/testglue/ordertable/OrderTableTestGlueConfiguration.java @@ -117,4 +117,33 @@ public void changeNumberOfGuestsResponse(String name, String number) { assertThat(orderTable.getNumberOfGuests()).isEqualTo(Integer.parseInt(number)); } + + @TestGlueOperation("{} 주문 테이블을 정리하면") + public void clear(String name) { + OrderTable orderTable = getAsType(name, OrderTable.class); + + TestGlueResponse response = createResponse(() -> orderTableService.clear(orderTable.getId())); + + put("orderTableResponse", response); + } + + @TestGlueOperation("주문 테이블은 초기화 된다") + public void clearResponse() { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isTrue(); + + OrderTable orderTable = orderTableRepository.findById(response.getData().getId()) + .orElseThrow(EntityNotFoundException::new); + + assertThat(orderTable.isOccupied()).isFalse(); + assertThat(orderTable.getNumberOfGuests()).isZero(); + } + + @TestGlueOperation("주문 테이블 초기화에 실패한다") + public void clear_fail() { + TestGlueResponse response = getAsType("orderTableResponse", TestGlueResponse.class); + + assertThat(response.isOk()).isFalse(); + } } diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java b/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java index 03ff1d333..22f78b189 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueSupport.java @@ -2,6 +2,7 @@ import java.util.function.Supplier; import kitchenpos.util.testglue.test.TestGlueResponse; +import org.junit.jupiter.api.BeforeEach; public class TestGlueSupport implements TestGlueContextAware { @@ -20,6 +21,11 @@ public void testGlueContext(TestGlueValueContext testGlueValueContext) { this.testGlueValueContext = testGlueValueContext; } + @BeforeEach + void setUp() { + testGlueValueContext.clear(); + } + public TestGlueResponse createResponse(Runnable runnable) { try { return TestGlueResponse.ok(new Object()); diff --git a/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java b/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java index 4bdd3746b..66016d9a1 100644 --- a/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java +++ b/src/test/java/kitchenpos/util/testglue/TestGlueValueContext.java @@ -2,7 +2,9 @@ import java.util.HashMap; import java.util.Map; +import org.springframework.stereotype.Component; +@Component public class TestGlueValueContext { private final Map storage; @@ -23,4 +25,8 @@ public T getAsType(String key, Class type) { return type.cast(o); } + + public void clear() { + storage.clear(); + } }