
@Repository와 @Component를 붙여주면 됩니다.package com.example.tdd_study.product;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
@Repository
public class ProductRepository {
private Map<Long, Product> persistence = new HashMap<>();
private Long sequence = 0L;
public void save(Product product) {
product.assignId(++sequence);
persistence.put(product.getId(), product);
}
}@Service 어노테이션을 붙여줍니다.package com.example.tdd_study.product;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public void register(String name, int price) {
Product product = new Product(name, price);
productRepository.save(product);
}
}코드를 수정하고 어노테이션을 붙였는데, 기존 테스트 코드를 고쳐야 할까요?
ProductServiceTest)는 순수한 자바 단위 테스트이기 때문에, 클래스에 어노테이션이 붙든 말든 상관없이 잘 돌아갑니다.
이것이 바로 상품 가격 정책: 상품 가격은 1000원 단위로만 설정할 수 있다. (예: 4500원 불가능, 4000원 가능)
package com.example.tdd_study.product;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class ProductTest {
@Test
void 상품_가격은_1000원_단위여야_한다() {
assertThatThrownBy(() -> new Product("상품", 1500))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("1000원 단위");
}
}// ... 기존 import 생략
@Getter
public class Product {
// ... 필드 생략
public Product(String name, int price) {
Assert.hasText(name, "상품명은 필수입니다.");
Assert.isTrue(price > 0, "상품 가격은 0보다 커야 합니다.");
// 추가된 로직
Assert.isTrue(price % 1000 == 0, "상품 가격은 1000원 단위여야 합니다.");
this.name = name;
this.price = price;
}
// ... 메서드 생략
}new Product()만 하면 됩니다.@Service, @Repository를 붙여 스프링이 관리하도록 했지만, 단위 테스트는 여전히 가볍게 유지할 수 있습니다.