[TIL]JAVA사전스터디_연산자, 조건문, 반복문, 배열, 컬렉션
[TIL]JAVA사전스터디_기본형 변수, 참조형 변수, 형변환📌 자바 개발 환경JRE(Java Runtime Environment): 자바 실행 환경으로 JRE(JVM)만 있다면 Java 프로그램을 실행만 시킬 수 있음: .class파일만 실행 가능
success-notes.tistory.com

해당 포스트는 "실전! 스프링부트 상품 주문 API 개발로 알아보는 TDD" 강의를 수강하여 작성한 글입니다.
📌 오늘 얻은 지식
❗️왜 @Test의 접근자는 왜 public이어야 하는가?
현재 Junit는 테스트 클래스의 테스트 메서드를 자바의 reflection api를 통해 호출
➡️ 초기 JUnit이 만들어지는 때 사용했던 JDK 1.1에서는 relfection에서 public 메서드만 허용하여 현재까지 @Test 클래스의 접근제어자가 public이 되었다.
public class serviceTest{
@Test
void 상품등록(){
// 테스트코드
}
}
➕ JUnit의 메서드는 모두 public이어야 한다.
@Test 어노테이션이 붙은 메소드는 접근제어자가 public임
public class ServiceTest{
@Test
public void 상품등록_1(){
// Test 메소드이기 때문에 접근제어자가 public
}
private void 상품등록_2(){
// Test 메소드가 아니기 때문에 접근제어자가 private이어도 괜찮음
}
}
❗️RECORD란?
RECORD란 JAVA 14에서 처음 소개된 클래스 타입으로, 변경 불가(immutable) 데이터 객체를 쉽게 만들 수 있다.
기존의 클래스와 비슷하지만, 더 간결하고 효율적으로 데이터 객체를 생성 가능하도록 설계되었다.
1) 기존방법
public class Student{
private String name;
private int age;
public Student(String name, int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
2) Record 방법
public record Student(String name, int age){
// 기존 방법에 비해 간결
}
3) 차이점
기존 방법 | Record 방법 | |
차이점 | 모든 필드에 final 선언 필드값을 모두 포함한 생성자 접근자 메소드 클래스의 상속을 제한하려면 클래스 레벨에도 final 선언 |
필드 캡슐화 생성자 메소드 접근자 메소드 ➡️ 자동생성 equals 메소드 hashcode 메소드 toString 메소드 |
➡️ 컴파일 타임에 컴파일러가 코드를 추가
접근자 메서드 호출
Record 클래스는 키워드를 사용하여 레코드 개체(레코드 클래스의 인스턴스)를 생성
// 기존 방법
Student student1 = new Student("choi",25);
System.out.println(student1.getName());
// Record
Student student2 = new Student("park", 20);
System.out.println(student2.length()); //해당 접근자 메서드 호출
👩🏻💻 작성 코드
test/product/ProductServiceTest.java
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
// 왜 public을 삭제하나?
class ProductServiceTest {
private ProductService productService;
private ProductPort productPort;
private ProductRepository productRepository;
@BeforeEach
void setUp(){
productRepository = new ProductRepository();
productPort = new ProductAdapter(productRepository);
productService = new ProductService(productPort);
}
@Test
void 상품등록(){
final AddProductRequest request = 상품등록요청_생성();
productService.addProduct(request);
}
private AddProductRequest 상품등록요청_생성() {
final String name = "상품명";
final int price = 1000;
final DiscountPolicy discountPolicy = DiscountPolicy.NONE;
return new AddProductRequest(name, price, discountPolicy);
}
}
main/product/AddProductRequest.java
import org.springframework.util.Assert;
record AddProductRequest(String name, int price, DiscountPolicy discountPolicy) {
public AddProductRequest {
Assert.hasText(name, "상품명은 필수입니다.");
Assert.isTrue(price > 0, "상품 가격은 0보다 커야 합니다.");
Assert.notNull(discountPolicy, "할인 정책은 필수입니다.");
}
}
main/product/DiscountPolicy.java
enum DiscountPolicy {
NONE
}
main/product/Product.java
import org.springframework.util.Assert;
class Product {
private final DiscountPolicy discountPolicy;
private final int price;
private final String name;
private Long id;
public Product(final String name, final int price, final DiscountPolicy discountPolicy) {
Assert.hasText(name, "상품명은 필수입니다.");
Assert.isTrue(price > 0, "상품 가격은 0보다 커야 합니다.");
Assert.notNull(discountPolicy, "할인 정책은 필수입니다.");
this.name = name;
this.price = price;
this.discountPolicy = discountPolicy;
}
public Long getId() {
return id;
}
public void assignId(Long id) {
this.id = id;
}
}
main/product/ProductAdapter.java
class ProductAdapter implements ProductPort {
private final ProductRepository productRepository;
ProductAdapter(ProductRepository productRepository) {
this.productRepository = productRepository;
}
@Override
public void save(Product product) {
productRepository.save(product);
}
}
main/product/ProductPort.java
interface ProductPort {
void save(final Product product);
}
main/product/ProductRepositort.java
class ProductRepository {
private Long sequence = 0L;
private Map<Long, Product> persistence = new HashMap<>();
public void save(final Product product) {
product.assignId(++sequence);
persistence.put(product.getId(), product);
}
}
main/product/ProductService.java
class ProductService {
private final ProductPort productPort;
ProductService(ProductPort productPort) {
this.productPort = productPort;
}
public void addProduct(AddProductRequest request) {
final Product product = new Product(request.name(), request.price(), request.discountPolicy());
productPort.save(product);
}
}
🧐 내가 파악한 구조

본 포스팅은 공부를 위해 작성한 것이므로, 틀린 내용이 있을 수 있습니다.
틀린 내용을 댓글을 통해 알려주시면 수정하도록 하겠습니다:)
📌 참고사이트
@Test 메소드 접근제어자 - https://groups.google.com/g/ksug/c/xpJpy8SCrEE
RECORD - https://docs.oracle.com/en/java/javase/22/language/records.html
'개발 > TIL' 카테고리의 다른 글
[TIL][VSCode] html 확장자 인식 안됨 - html ➡️Django (0) | 2024.05.21 |
---|---|
[TIL]방법론 스터디_TDD 테스트 예제 & [failed to load applicationcontext] 에러 & [Error creating bean with name] 에러 (0) | 2024.05.20 |
[TIL]방법론스터디_주문요청 API & JPA console 설정 (0) | 2024.05.16 |
[TIL]JAVA사전스터디_연산자, 조건문, 반복문, 배열, 컬렉션 (0) | 2024.05.08 |
[TIL]JAVA사전스터디_기본형 변수, 참조형 변수, 형변환 (0) | 2024.05.08 |