Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3단계 - 테스트를 통한 코드 보호 #391

Open
wants to merge 21 commits into
base: bperhaps
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
24ee5a2
feat(kitchenpos): readme 작성.
bperhaps Aug 26, 2022
9a843ce
refactor(kitchenpos): order line item -> 주문메뉴정보로 변경.
bperhaps Aug 27, 2022
ae8d002
refactor(kitchenpos): 주문의 상태 변화 표현.
bperhaps Aug 27, 2022
06cf928
test(kitchenpos): testGlue 뼈대 생성.
bperhaps Sep 2, 2022
23a9612
test(kitchenpos): testGlue context 등록 및 실행 구현.
bperhaps Sep 2, 2022
1392135
test(kitchenpos): testGlue runner 구현.
bperhaps Sep 2, 2022
d15f3e9
test(kitchenpos): testGlue 패키지 변경.
bperhaps Sep 3, 2022
ee3c941
test(kitchenpos): testGlue support 생성.
bperhaps Sep 3, 2022
ce35cba
test(kitchenpos): testGlue 파라메터 추가.
bperhaps Sep 3, 2022
b74de49
test(kitchenpos): product 비즈니스 테스트.
bperhaps Sep 3, 2022
1e7030f
test(kitchenpos): fixture 패키지 이동.
bperhaps Sep 3, 2022
99a2fcb
test(kitchenpos): 상품 생성 테스트 작성.
bperhaps Sep 4, 2022
8ad0b7e
test(kitchenpos): testGlue 다중 파라메터 지원.
bperhaps Sep 4, 2022
8efcf13
test(kitchenpos): 상품 테스트 구현.
bperhaps Sep 4, 2022
960784d
docs(kitchenpos): readme 업데이트.
bperhaps Sep 4, 2022
3259c68
test(kitchenpos): 메뉴 그룹 테스트 생성.
bperhaps Sep 4, 2022
a88fc1c
test(kitchenpos): 깨지느 테스트 fix
bperhaps Sep 19, 2022
d5b5817
test(kitchenpos): menu 테스트 작성.
bperhaps Sep 20, 2022
7ab55fd
test(kitchenpos): orderTable test 작성.
bperhaps Oct 3, 2022
0859bd6
test(kitchenpos): order test 작성.
bperhaps Oct 3, 2022
ffeb412
test(kitchenpos): order table clear 테스트 구현.
bperhaps Oct 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 73 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,97 +13,97 @@ docker compose -p kitchenpos up -d
## 요구 사항

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BDD방식의 테스트코드 작성을 진행하면서 느낀게, 과연 인수테스트가 도메인 보호로서의 역할을 하는지 잘 모르겠다는 것 입니다.

인수조건을 만족하는지에 대해서는, 문서화된 형태로 보이고, 개발자가 아니더라도 읽을 수 있는 장점이 있는건 알겠지만, 조금 더 세세한 조건의 테스트를 진행하거나 할때는 생산성이 많이 떨어지고 오히려 보기 힘들어지더라구요. 역시 도메인 보호를 위해서는 integerationTest 나 mock slice test를 통해서 도메인 로직만 테스트하는게 좋았던걸까요? 저는 개인적으로는 그렇게 생각하는데 규남님 의견도 궁금합니다 !

사람마다 생각하는건 다르겠지만 일단 저도 인수 테스트만을 이용해 도메인 보호의 역할을 훌륭하게 수행할 수 있느냐? 라는 질문에 대해서는 의문이 있습니다. 인수 테스트가 아닌 통합 테스트 또한 마찬가지라고 생각해요.

이렇게 생각하는 이유는 인수 테스트든 통합 테스트든 하위 레이어의 도메인 모델이나 도메인 서비스 등 모든 부분에 대해 테스트 케이스를 작성하고 검증하는게 어렵다고 생각하기 때문이에요.
아무리 테스트를 꼼꼼히 잘 작성해도 인수 테스트, 통합 테스트 정도의 범위에서 바라보면 엣지 케이스를 누락할 수 있으며 또한 레이어 별로 달라지는 브랜치(if, else)에 따라 테스트 케이스가 너무 많아질 수 있습니다.
결국 인수 테스트든 통합 테스트든 위와 같은 문제 때문에 도메인의 모든 상황을 잘 커버할 수 없습니다.

인수 테스트와 통합 테스트가 쓸모없다는 얘길 하고 싶었던 건 아니에요, 당연한 이야기겠지만 도메인 로직, 클래스나 메소드 단위로 단위 테스트를 꼼꼼히 잘 작성하고 레이어 별 슬라이스 테스트를 잘 작성해주는게 중요하다는 말씀을 드리고 싶었어요.
단위 테스트가 꼼꼼히 작성된 이후 필요한 시나리오에 따라 통합 테스트나 인수 테스트를 추가해주시면 도메인 보호의 역할을 훌륭하게 수행할 수 있을거라 생각합니다.


### 메뉴 그룹
- [ ] 메뉴 그룹은 N개의 메뉴를 가질 수 있다.
- [ ] 메뉴그룹 이름은 비어있을 수 없다.
- [x] 메뉴 그룹은 N개의 메뉴를 가질 수 있다.
- [x] 메뉴그룹 이름은 비어있을 수 없다.

### 메뉴
- 생성
- [ ] 메뉴 가격은 비어있을 수 없다.
- [ ] 메뉴 가격은 음수일 수 없다.
- [ ] 메뉴는 특정 메뉴 그룹에 항상 속해야 한다.
- [ ] 메뉴는 N 개의 메뉴 상품을 가진다.
- [ ] 메뉴에 속한 상품은 모두 존재해야 한다.
- [ ] 메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다.
- [ ] 메뉴 이름은 비어있을 수 없다.
- [ ] 메뉴 이름에는 욕설이 포함될 수 없다.
- [x] 메뉴 가격은 비어있을 수 없다.
- [x] 메뉴 가격은 음수일 수 없다.
- [x] 메뉴는 특정 메뉴 그룹에 항상 속해야 한다.
- [x] 메뉴는 N 개의 메뉴 상품을 가진다.
- [x] 메뉴에 속한 상품은 모두 존재해야 한다.
- [x] 메뉴의 가격은 각 상품의 가격 * 각 상품의 재고 수 보다 클 수 없다.
- [x] 메뉴 이름은 비어있을 수 없다.
- [x] 메뉴 이름에는 욕설이 포함될 수 없다.

- 가격 변경
- [ ] 가격은 비어있거나 음수일 수 없다.
- [ ] 가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다.
- [ ] 변경하고자 하는 가격이 현재 가격과 같아선 안된다.
- [x] 가격은 비어있거나 음수일 수 없다.
- [x] 가격을 변경하고자 하는 메뉴는 반드시 존재해야 한다.
- [x] 변경하고자 하는 가격이 현재 가격과 같아선 안된다.

- 전시
- [ ] 메뉴는 반드시 존재해야 한다.
- [ ] 메뉴가 가지고 있는 각 메뉴 상품의 가격(수량 * 상품 가격)이 메뉴의 가격보다 작아야한다. //조건이 이상한데?, 생성 조건이랑 다름.
- [x] 메뉴는 반드시 존재해야 한다.
- [x] 메뉴가 가지고 있는 각 메뉴 상품의 가격(수량 * 상품 가격)이 메뉴의 가격보다 작아야한다. //조건이 이상한데?, 생성 조건이랑 다름.

- 미전시
- [ ] 메뉴는 반드시 존재해야 한다.
- [x] 메뉴는 반드시 존재해야 한다.

### 메뉴 상품
- 메뉴 상품은 메뉴에 포함된 각 상품의 수량를 관리한다.
- [ ] 메뉴 상품은 언제나 상품을 갖는다. (not null)
- [ ] 메뉴에 포함된 각 상품 수량이 음수일 수는 없다.
- [x] 메뉴 상품은 언제나 상품을 갖는다. (not null)
- [x] 메뉴에 포함된 각 상품 수량이 음수일 수는 없다.

### 상품
생성
- [ ] 상품의 가격은 비어있거나 음수여서는 안된다.
- [ ] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다.
- [x] 상품의 가격은 비어있거나 음수여서는 안된다.
- [x] 상품의 이름은 비어있거나 욕설이 포함돼서는 안된다.

가격 변경
- [ ] 가격은 비어있거나 0보다 작아서는 안된다.
- [ ] 상품은 존재해야 한다.
- [ ] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.)
- [ ] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다.
- [x] 가격은 비어있거나 0보다 작아서는 안된다.
- [x] 상품은 존재해야 한다.
- [x] 상품의 가격을 변경한 뒤, 상품을 들고있는 메뉴들의 가격 제약조건은 성립되어야 한다.(메뉴 가격이 전체 상품의 합보다 작아야함.)
- [x] 만일 만족하지 않는다면 메뉴를 미전시 상태로 바꾼다.

### 주문메뉴정보
- 주문메뉴정보는 주문에 포함된 각 메뉴의 수량을 관리한다.
- [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨).
- [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다.
- [ ] 홀이 아닐경우, 음수를 허용하지 않는다.
- [ ] 모든 메뉴는 전시중이어야 한다.
- [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다.
- [x] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨).
- [x] 홀에서 먹을 경우, 수량은 음수를 허용한다.
- [x] 홀이 아닐경우, 음수를 허용하지 않는다.
- [x] 모든 메뉴는 전시중이어야 한다.
- [x] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다.

### 주문
생성
```
주문의 상태 변화
WAITING
```
- [ ] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN)
- [ ] 타입은 비어있을 수 없다.
- [ ] 주문은 여러 주문메뉴정보를 가질 수 있다.
- [ ] 주문은 적어도 하나의 주문메뉴정보를 가져야 한다.
- [ ] 주문에 포함된 주문메뉴정보는, 주문메뉴정보의 제약조건을 모두 만족해야 한다.
- [ ] 주문메뉴정보의 메뉴는 항상 존재해야 한다(메뉴가 없으면 안됨).
- [ ] 홀에서 먹을 경우, 수량은 음수를 허용한다.
- [ ] 홀이 아닐경우, 음수를 허용하지 않는다.
- [ ] 모든 메뉴는 전시중이어야 한다.
- [ ] 메뉴 가격과 주문메뉴정보에 명시된 가격은 동일해야 한다.
- [ ] 주문의 초기 상태는 WAITING이다.
- [ ] 주문의 타입이 DEVIVERY라면, 주소를 필수로 입력받는다.
- [ ] 주소는 널이거나 비어있지 않다.
- [ ] 주문의 타입이 EAT_IN이라면, 주문 테이블을 필수로 입력 받는다.
- [ ] 주문 테이블의 상태는 occupied상태가 아니어야 한다.
- [ ] 주문 테이블은 존재해야 한다.
- [x] 주문은 배달, 테이크아웃, 홀 타입으로 나누어 진다. (DELIVERY, TAKEOUT, EAT_IN)
- [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
```
Expand All @@ -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
```
Expand All @@ -137,29 +137,29 @@ 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 상태로 변경된다.

## 주문 테이블
생성
- [ ] 테이블 이름은 비어있을 수 없다.
- [x] 테이블 이름은 비어있을 수 없다.

주문 테이블 sit
- [ ] 주문 테이블은 존재해야 한다.
- [ ] 주문 테이블이 occupied상태가 된다.
- [x] 주문 테이블은 존재해야 한다.
- [x] 주문 테이블이 occupied상태가 된다.

주문 테이블 clear
- [ ] 주문 테이블은 존재해야 한다.
- [ ] 주문 테이블에 연관된 주문은 모두 COMPLETED 상태여야 한다.
- [ ] 주문 테이블은 초기화 된다.
- [x] 주문 테이블은 존재해야 한다.
- [x] 주문 테이블에 연관된 주문은 모두 COMPLETED 상태여야 한다.
- [x] 주문 테이블은 초기화 된다.

주문 테이블 changeNumberOfGuest
- [ ] 손님 수는 음수일 수 없다.
- [ ] 주문 테이블은 존재해야 한다.
- [ ] 주문 테이블은 occupied상태여서는 안된다.
- [x] 손님 수는 음수일 수 없다.
- [x] 주문 테이블은 존재해야 한다.
- [x] 주문 테이블은 occupied상태여서는 안된다.

## 용어 사전

Expand Down
39 changes: 39 additions & 0 deletions src/test/java/kitchenpos/application/MenuGroupServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package kitchenpos.application;

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;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@EnableTestGlue
@SpringBootTest
class MenuGroupServiceTest extends TestIsolationSupport {

@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();
}
}
Loading