Skip to content

Commit ae4a468

Browse files
author
seungjoo.jeong
committed
feat(test) usecase에 대한 테스트코드 작성
- usecase 테스트코드 작성 - 테스트 도우미 fixtures, accessor 추가
1 parent a651a16 commit ae4a468

13 files changed

+428
-18
lines changed

src/main/java/kitchenpos/menu/adapter/in/MenuDisplayingRearranger.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public MenuDisplayingRearranger(final MenuUseCase menuUseCase) {
1111
this.menuUseCase = menuUseCase;
1212
}
1313

14-
public void rearrange(final UUID productId) {
14+
public void execute(final UUID productId) {
1515
menuUseCase.rearrangeDisplaying(productId);
1616
}
1717
}

src/main/java/kitchenpos/product/adapter/out/DefaultProductPriceChangeEventPublisher.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package kitchenpos.product.adapter.out;
22

3+
import static kitchenpos.support.ParameterValidateUtils.checkNotNull;
4+
35
import java.util.UUID;
46
import kitchenpos.menu.adapter.in.MenuDisplayingRearranger;
57
import kitchenpos.product.application.port.out.ProductPriceChangeEventPublisher;
8+
import kitchenpos.product.support.constant.Name;
69

710
public class DefaultProductPriceChangeEventPublisher implements ProductPriceChangeEventPublisher {
811

@@ -14,6 +17,8 @@ public DefaultProductPriceChangeEventPublisher(final MenuDisplayingRearranger re
1417

1518
@Override
1619
public void publish(final UUID id) {
17-
rearranger.rearrange(id);
20+
checkNotNull(id, Name.ID);
21+
22+
rearranger.execute(id);
1823
}
1924
}

src/main/java/kitchenpos/product/application/DefaultProductRegistrationUseCase.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package kitchenpos.product.application;
22

3+
import static kitchenpos.product.support.constant.Name.PRICE;
4+
import static kitchenpos.support.ParameterValidateUtils.checkNotNull;
5+
36
import kitchenpos.product.application.port.in.ProductRegistrationUseCase;
47
import kitchenpos.product.application.port.out.ProductNewRepository;
58
import kitchenpos.product.domain.Name;
9+
import kitchenpos.product.domain.ProductName;
610
import kitchenpos.product.domain.ProductNameFactory;
711
import kitchenpos.product.domain.ProductNew;
812
import kitchenpos.product.domain.ProductPrice;
@@ -21,10 +25,15 @@ public DefaultProductRegistrationUseCase(final ProductNameFactory productNameFac
2125
}
2226

2327
@Override
24-
public void register(final Name productNameCandidate, final ProductPrice price) {
28+
public ProductDTO register(final Name productNameCandidate, final ProductPrice price) {
29+
checkNotNull(productNameCandidate, "productNameCandidate");
30+
checkNotNull(price, PRICE);
31+
32+
final ProductName productName = productNameFactory.create(productNameCandidate);
33+
2534
final ProductNew product
26-
= ProductNew.newOf(productNameFactory.create(productNameCandidate), price);
35+
= repository.save(ProductNew.newOf(productName, price));
2736

28-
repository.save(product);
37+
return new ProductDTO(product);
2938
}
3039
}

src/main/java/kitchenpos/product/application/ProductDTO.java

+4
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ public String toString() {
3131
.add("name", name)
3232
.toString();
3333
}
34+
35+
public UUID getId() {
36+
return id;
37+
}
3438
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package kitchenpos.product.application.port.in;
22

3+
import kitchenpos.product.application.ProductDTO;
4+
import kitchenpos.product.application.exception.ContainsProfanityException;
35
import kitchenpos.product.domain.Name;
46
import kitchenpos.product.domain.ProductPrice;
57

68
public interface ProductRegistrationUseCase {
79

810
/**
9-
* @throws IllegalArgumentException nameCandidate에 비속어가 포함되어 있을 때
11+
* @throws ContainsProfanityException nameCandidate에 비속어가 포함되어 있을 때
1012
*/
11-
void register(final Name productNameCandidate, final ProductPrice price);
13+
ProductDTO register(final Name productNameCandidate, final ProductPrice price);
1214
}

src/test/java/kitchenpos/product/Fixtures.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
package kitchenpos.product;
22

33
import kitchenpos.product.domain.Name;
4+
import kitchenpos.product.domain.ProductNameAccessor;
5+
import kitchenpos.product.domain.ProductNew;
46
import kitchenpos.product.domain.ProductPrice;
57

68
public final class Fixtures {
79

810
public static final String TEST_NAME = "닭강정";
911
public static final Name VALID_NAME = new Name(TEST_NAME);
10-
12+
1113
public static final long TEST_PRICE_VALUE = 1_000L;
12-
public static final ProductPrice VALID_PRODUCT_PRIECE = ProductPrice.of(TEST_PRICE_VALUE);
14+
public static final ProductPrice VALID_PRODUCT_PRICE = ProductPrice.of(TEST_PRICE_VALUE);
15+
16+
public static ProductNew create(final long price) {
17+
return create(TEST_NAME, price);
18+
}
19+
20+
public static ProductNew create(final String name, final long price) {
21+
return ProductNew.newOf(
22+
ProductNameAccessor.create(new Name(name)),
23+
ProductPrice.of(price));
24+
}
1325

1426
private Fixtures() {
1527
throw new UnsupportedOperationException();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package kitchenpos.product.adapter.out;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
import static org.mockito.ArgumentMatchers.any;
5+
import static org.mockito.Mockito.never;
6+
import static org.mockito.Mockito.verify;
7+
8+
import java.util.UUID;
9+
import kitchenpos.menu.adapter.in.MenuDisplayingRearranger;
10+
import kitchenpos.product.application.port.out.ProductPriceChangeEventPublisher;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.DisplayNameGeneration;
13+
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.ExtendWith;
16+
import org.junit.jupiter.params.ParameterizedTest;
17+
import org.junit.jupiter.params.provider.NullSource;
18+
import org.mockito.Mock;
19+
import org.mockito.junit.jupiter.MockitoExtension;
20+
21+
@DisplayNameGeneration(ReplaceUnderscores.class)
22+
@ExtendWith(MockitoExtension.class)
23+
class DefaultProductPriceChangeEventPublisherTest {
24+
25+
@Mock
26+
private MenuDisplayingRearranger mockRearranger;
27+
28+
private ProductPriceChangeEventPublisher publisher;
29+
30+
@BeforeEach
31+
void setUp() {
32+
publisher = new DefaultProductPriceChangeEventPublisher(mockRearranger);
33+
}
34+
35+
@ParameterizedTest
36+
@NullSource
37+
void publish_invalid_parameters_id가_null이면_예외를_발생시킨다(final UUID value) {
38+
39+
// when & then
40+
assertThatThrownBy(() -> publisher.publish(value))
41+
.isExactlyInstanceOf(IllegalArgumentException.class);
42+
}
43+
44+
@ParameterizedTest
45+
@NullSource
46+
void publish_invalid_parameters_id가_null이면_rearranger는_실행되지_않는다(final UUID value) {
47+
48+
// when
49+
try {
50+
publisher.publish(value);
51+
} catch (final Exception ignored) {
52+
}
53+
54+
// then
55+
// verify
56+
verify(mockRearranger, never())
57+
.execute(any());
58+
}
59+
60+
@Test
61+
void publish_id를_인자로_rerranger가_실행된다() {
62+
// given
63+
final UUID id = UUID.randomUUID();
64+
65+
// when
66+
publisher.publish(id);
67+
68+
// then
69+
// verify
70+
verify(mockRearranger)
71+
.execute(id);
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package kitchenpos.product.application;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.List;
6+
import kitchenpos.product.Fixtures;
7+
import kitchenpos.product.application.port.in.ProductFindUseCase;
8+
import kitchenpos.product.application.port.out.ProductNewRepository;
9+
import kitchenpos.product.domain.ProductNew;
10+
import kitchenpos.product.fakerepository.ProductNewFakeRepository;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.DisplayNameGeneration;
13+
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.ExtendWith;
16+
import org.mockito.junit.jupiter.MockitoExtension;
17+
18+
@DisplayNameGeneration(ReplaceUnderscores.class)
19+
@ExtendWith(MockitoExtension.class)
20+
class DefaultProductFindUseCaseTest {
21+
22+
private ProductNewRepository repository;
23+
24+
private ProductFindUseCase useCase;
25+
26+
@BeforeEach
27+
void setUp() {
28+
repository = new ProductNewFakeRepository();
29+
30+
useCase = new DefaultProductFindUseCase(repository);
31+
}
32+
33+
@Test
34+
void findAll_저장된_모든_음식_목록을_dto로_변환하여_반환한다() {
35+
36+
// given
37+
final ProductNew product1 = repository.save(Fixtures.create("dummy1", 1_000L));
38+
final ProductNew product2 = repository.save(Fixtures.create("dummy2", 3_000L));
39+
40+
// when
41+
final List<ProductDTO> actual = useCase.findAll();
42+
43+
// then
44+
final ProductDTO expected1 = new ProductDTO(product1);
45+
final ProductDTO expected2 = new ProductDTO(product2);
46+
47+
assertThat(actual)
48+
.usingRecursiveFieldByFieldElementComparator()
49+
.contains(expected1, expected2);
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package kitchenpos.product.application;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.Mockito.never;
7+
import static org.mockito.Mockito.verify;
8+
9+
import java.util.UUID;
10+
import kitchenpos.product.Fixtures;
11+
import kitchenpos.product.application.exception.NotExistProductException;
12+
import kitchenpos.product.application.port.in.ProductPriceChangeUseCase;
13+
import kitchenpos.product.application.port.out.ProductNewRepository;
14+
import kitchenpos.product.application.port.out.ProductPriceChangeEventPublisher;
15+
import kitchenpos.product.domain.ProductNew;
16+
import kitchenpos.product.domain.ProductPrice;
17+
import kitchenpos.product.fakerepository.ProductNewFakeRepository;
18+
import org.junit.jupiter.api.BeforeEach;
19+
import org.junit.jupiter.api.DisplayNameGeneration;
20+
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.ExtendWith;
23+
import org.junit.jupiter.params.ParameterizedTest;
24+
import org.junit.jupiter.params.provider.NullSource;
25+
import org.mockito.Mock;
26+
import org.mockito.junit.jupiter.MockitoExtension;
27+
28+
@DisplayNameGeneration(ReplaceUnderscores.class)
29+
@ExtendWith(MockitoExtension.class)
30+
class DefaultProductPriceChangeUseCaseTest {
31+
32+
@Mock
33+
private ProductPriceChangeEventPublisher mockEventPublisher;
34+
35+
private ProductNewRepository repository;
36+
37+
private ProductPriceChangeUseCase useCase;
38+
39+
@BeforeEach
40+
void setUp() {
41+
repository = new ProductNewFakeRepository();
42+
43+
useCase = new DefaultProductPriceChangeUseCase(repository, mockEventPublisher);
44+
}
45+
46+
47+
@ParameterizedTest
48+
@NullSource
49+
void change_invalid_parameters_id가_null이면_예외를_발생시킨다(final UUID value) {
50+
51+
// when & then
52+
assertThatThrownBy(() -> useCase.change(value, Fixtures.VALID_PRODUCT_PRICE))
53+
.isExactlyInstanceOf(IllegalArgumentException.class);
54+
}
55+
56+
@ParameterizedTest
57+
@NullSource
58+
void change_invalid_parameters_price가_null이면_예외를_발생시킨다(final ProductPrice value) {
59+
60+
// when & then
61+
assertThatThrownBy(() -> useCase.change(UUID.randomUUID(), value))
62+
.isExactlyInstanceOf(IllegalArgumentException.class);
63+
}
64+
65+
@Test
66+
void change_id에_해당하는_음식이_없으면_예외를_발생시킨다() {
67+
68+
// when & then
69+
assertThatThrownBy(() -> useCase.change(UUID.randomUUID(), Fixtures.VALID_PRODUCT_PRICE))
70+
.isExactlyInstanceOf(NotExistProductException.class);
71+
}
72+
73+
@Test
74+
void change_id에_해당하는_음식이_없으면_가격변경_이벤트를_발행하지_않는다() {
75+
// given
76+
77+
// when
78+
throwExceptionScenario();
79+
80+
// then
81+
verify(mockEventPublisher, never())
82+
.publish(any());
83+
}
84+
85+
private void throwExceptionScenario() {
86+
try {
87+
useCase.change(UUID.randomUUID(), Fixtures.VALID_PRODUCT_PRICE);
88+
} catch (final Exception ignored) {
89+
}
90+
}
91+
92+
@Test
93+
void change_입력받은_가격으로_음식_가격을_변경시킨다() {
94+
// given
95+
final ProductNew product = repository.save(Fixtures.create(5_000L));
96+
97+
// when
98+
useCase.change(product.getId(), ProductPrice.of(10_000L));
99+
100+
// then
101+
assertThat(product.getPrice())
102+
.isEqualTo(ProductPrice.of(10_000L));
103+
}
104+
105+
@Test
106+
void change_가격이_변경되면_가격변경_이벤트를_발행한다() {
107+
// given
108+
final ProductNew product = repository.save(Fixtures.create(5_000L));
109+
110+
// when
111+
useCase.change(product.getId(), ProductPrice.of(10_000L));
112+
// then
113+
// verify
114+
verify(mockEventPublisher)
115+
.publish(product.getId());
116+
}
117+
}

0 commit comments

Comments
 (0)