코드 그라데이션

웹 페이지 만들기 (1) 요구사항 분석 및 상품 도메인 개발 본문

Spring/MVC 1

웹 페이지 만들기 (1) 요구사항 분석 및 상품 도메인 개발

완벽한 장면 2023. 10. 30. 22:18

프로젝트 기본 세팅

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.15'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '11'
}

configurations {
    compileOnly {
       extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

 

서비스 제공 흐름

- 검정색이 컨트롤러, 뷰는 항상 클라이언트 통해서 호출된다.

 

 

요구사항 분석

상품 도메인 모델

  • 상품 ID
  • 상품명
  • 가격
  • 수량


상품 관리 기능

  • 상품 목록
  • 상품 상세
  • 상품 등록
  • 상품 수정

 

 

상품 도메인 개발

Item - 상품 객체

@Data // 예제이므로 이 어노테이션 사용
@NoArgsConstructor
public class Item {
    private Long id;
    private String itemName;
    // 아래 두 개는 null 일 수도 있기 때문에 Integer
    private Integer price;
    private Integer quantity;
    
    
    public Item(String itemName, Integer price, Integer quantity) {
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }
}

 

ItemRepository - 상품 저장소

(역시 예제라서 간단하게 class로 만듦)

@Repository // 인터페이스가 아니므로 붙인 듯. 안에 @Component 있음
public class ItemRepository {

    private static final Map<Long, Item> store = new HashMap<>();
    // 실무 멀티 스레드 환경에서는 HashMap 을 쓰면 안 된다.
    // 사용하고 싶다면 currentHashMap 을 써야한다.
    private static long sequence = 0L;

    public Item save(Item item) {
        item.setId(++sequence);
        store.put(item.getId(), item);
        return item;
    }

    public Item findById(Long id) {
        return store.get(id);
    }

    public List<Item> findAll() {
        return new ArrayList<>(store.values());
    }

    public void update(Long itemId, Item item) {
        Item findItem = findById(itemId);
        findItem.setItemName(item.getItemName());
        findItem.setPrice(item.getPrice());
        findItem.setQuantity(item.getQuantity());
    }

    public void clearStore() { // 테스트용 메서드
        store.clear();
    }

}

 

 

ItemRepositoryTest

이거 역시 mock 사용하지 않고 그냥 객체 직접 생성

class ItemRepositoryTest {

    ItemRepository itemRepository = new ItemRepository();

    @AfterEach
    void afterEach() {
        itemRepository.clearStore();
    }

    @DisplayName("상품 저장 테스트")
    @Test
    void save() {
        //given
        Item item = new Item("itemA", 10000, 10);

        //when
        Item savedItem = itemRepository.save(item);

        //then
        Item findItem = itemRepository.findById(item.getId());
        assertThat(findItem).isEqualTo(savedItem);
    }

    @DisplayName("상품 전체 저장")
    @Test
    void findAll() {
        //given
        Item item1 = new Item("item1", 10000, 10);
        Item item2 = new Item("item2", 20000, 20);

        itemRepository.save(item1);
        itemRepository.save(item2);

        //when
        List<Item> result = itemRepository.findAll();

        //then
        assertThat(result.size()).isEqualTo(2);
        assertThat(result).contains(item1, item2);
    }

    @DisplayName("아이템 업데이트")
    @Test
    void updateItem() {
        //given
        Item item = new Item("item1", 10000, 10);

        Item savedItem = itemRepository.save(item);
        Long itemId = savedItem.getId();

        //when
        Item updateParam = new Item("item2", 20000, 30);
        itemRepository.update(itemId, updateParam);

        Item findItem = itemRepository.findById(itemId);

        //then
        assertThat(findItem.getItemName()).isEqualTo(updateParam.getItemName());
        assertThat(findItem.getPrice()).isEqualTo(updateParam.getPrice());
        assertThat(findItem.getQuantity()).isEqualTo(updateParam.getQuantity());
    }
}

 

728x90
Comments