Skip to content

Commit

Permalink
[Order API TDD] 상품 조회 기능 구현하기
Browse files Browse the repository at this point in the history
  • Loading branch information
jihunparkme committed Feb 26, 2024
1 parent 6161a4c commit 31059fc
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 23 deletions.
12 changes: 12 additions & 0 deletions product-order-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ final AddProductRequest request = new AddProductRequest(name, price, discountPol
(5) 레파지포리 생성
- 테스트에서는 데이터를 인메모리(Map)로 관리

> Then -> Given -> When 순서로 적성해 보기
.

**Move Inner class for test to Upper level**
Expand All @@ -42,6 +44,13 @@ API 테스트를 위해 io.rest-assured:rest-assured 사용하기
- 데이터가 캐싱이 되어 table sequence 가 꼬여 다른 테스트가 깨질 수 있음(ex. table sequence)
- 격리 방법은 [3월 우아한테크세미나 / 우아한ATDD](https://www.youtube.com/watch?v=ITVpmjM4mUE) 참고

## JPA 적용하기

기존 in-memory 형태의 데이터 저장소를 jpa 로 적용

## 상품 조회 기능 구현하기

상품 등록 구현으로 이미 기반이 잡혀 있으므로 POJO 부터 테스트를 시작하지 않고 @SpringBootTest 로 시작

---

Expand All @@ -51,6 +60,9 @@ Point.
- Assert in constructor
- rest-assured api test
- var type
- HttpStatus
- 200 OK
- 201 CREATE

---

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.productorderservice.product;

import org.springframework.util.Assert;

record GetProductResponse(
long id,
String name,
int price,
DiscountPolicy discountPolicy
) {
GetProductResponse {
Assert.notNull(id, "상품 ID는 필수입니다.");
Assert.hasText(name, "상품명은 필수입니다.");
Assert.isTrue(price > 0, "상품 가격은 0보다 커야 합니다.");
Assert.notNull(discountPolicy, "할인 정책은 필수입니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

@Component
class ProductAdapter implements ProductPort {

private final ProductRepository productRepository;

ProductAdapter(final ProductRepository productRepository) {
Expand All @@ -14,4 +15,10 @@ class ProductAdapter implements ProductPort {
public void save(final Product product) {
productRepository.save(product);
}

@Override
public Product getProduct(final long productId) {
return productRepository.findById(productId)
.orElseThrow(() -> new IllegalArgumentException("상품이 존재하지 않습니다."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

interface ProductPort {
void save(final Product product);

Product getProduct(long productId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ public ResponseEntity<Void> addProduct(@RequestBody final AddProductRequest requ

return ResponseEntity.status(HttpStatus.CREATED).build();
}

public GetProductResponse getProduct(final long productId) {
final Product product = productPort.getProduct(productId);

return new GetProductResponse(
product.getId(),
product.getName(),
product.getPrice(),
product.getDiscountPolicy());
}
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,19 @@
package com.example.productorderservice.product;

import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

import static org.assertj.core.api.Assertions.assertThat;

class ProductApiTest extends ApiTest {

@Test
void 상품등록() {
final var request = getAddProductRequest();
final var request = ProductSteps.getAddProductRequest();

final var response = requestAddProduct(request);
final var response = ProductSteps.requestAddProduct(request);

assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value());
}

private ExtractableResponse<Response> requestAddProduct(final AddProductRequest request) {
return RestAssured.given().log().all() // 요청 로그 남기기
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(request)
.when()
.post("/products")
.then()
.log().all().extract();
}

private AddProductRequest getAddProductRequest() {
final String name = "상품명";
final int price = 1000;
final DiscountPolicy discountPolicy = DiscountPolicy.NONE;
return new AddProductRequest(name, price, discountPolicy); // 02. Request 클래스 생성
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.example.productorderservice.product;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@SpringBootTest
class ProductServiceTest {

@Autowired
private ProductService productService;

@Test
void 상품조회() {
// 상품 등록
productService.addProduct(ProductSteps.getAddProductRequest());
final long productId = 1L;

// 상품 조회
final GetProductResponse response = productService.getProduct(productId);

// 상품의 응답 검증
assertThat(response).isNotNull();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.example.productorderservice.product;

import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.springframework.http.MediaType;

public class ProductSteps {
public static ExtractableResponse<Response> requestAddProduct(final AddProductRequest request) {
return RestAssured.given().log().all() // 요청 로그 남기기
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(request)
.when()
.post("/products")
.then()
.log().all().extract();
}

public static AddProductRequest getAddProductRequest() {
final String name = "상품명";
final int price = 1000;
final DiscountPolicy discountPolicy = DiscountPolicy.NONE;
return new AddProductRequest(name, price, discountPolicy); // 02. Request 클래스 생성
}
}

0 comments on commit 31059fc

Please sign in to comment.