[Spring Boot] 빌더(Builder) 패턴 및 단위 테스트

Use_Silver·2022년 2월 15일
0

Spring

목록 보기
9/10
post-thumbnail

빌더(Builder) 패턴?

빌더 패턴

  • 복잡한 객체의 생성 과정 및 표현 방법을 분리해 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴

빌더 패턴 장점

  • 어떤 필드에 어떤 값을 채워야 할지 명확히 지정할 수 있음
  • 필수 및 선택인자가 많아질수록 생성자 방식보다 가독성이 좋다
  • 자바빈 패턴(setter를 이용하는 방식)보다 안전함.
  • setter 생성을 방지하기 때문에 객체를 변경할 수 없음 (불변성 보장)

생성자 패턴 vs 빌더 패턴

1. 생성자 패턴 예시

public class Person {
	private String name;
	private int age;
	private String grade;
	
	public Person(String name, int age, String grade){
		this.name = name;
		this.age = age;
		this.grade = grade;
	}
	
	// Getter 
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String getGrade() {
		return grade;
	}	
}
String name = "jueun";
int age = 24;
String grade = "4";
Person p1 = new Person(name, age, grade);
// String type 변수가 위치가 바뀌어도 문제점 찾지 못함 
Person p2 = new Person(grade, age, name); 

2. 빌더 패턴 예시

public class Person {
	
	// final 키워드를 사용해 생성자를 통한 입력 
	private final String name, grade;
	private final int age;
	
	// 클래스 내에 static 형태의 내부 클래스(inner class) 생성
	protected static class Builder{
		private String name;
		private String grade;
		private int age;
		
		//name 입력값 받음 : return type을 Builder로 지정 후 this return
		public Builder name(String value) {
			name = value;
			return this;
		}
		
		//grade 입력값 받음
		public Builder grade(String value) {
			grade = value;
			return this;
		}
		
		//age 입력값 받음 
		public Builder age(int value) {
			age = value;
			return this;
		}		
		
		// build() 메소드 실행하면 this가 return 되도록 지정  
		public Person build() {
			return new Person(this);
		}		
	}
	
	// 생성자를 private으로 함 
	// 외부에서 접근 x + Builder 클래스에서 사용 가능 
	private Person(Builder builder){
		name = builder.name;
		age = builder.age;
		grade = builder.grade;
	}
	
	// 빌더 소환 : 외부에서 Person.builder() 형태로 접근 가능하게 static method로 생성 
	public static Builder builder() {
		return new Builder();
	}
	
	//Geter 생략 
}
String name = "jueun";
int age = 24;
String grade = "4";
Person p1 = Person.builder()
		        .name(name)
		        .age(age)
		        .grade(grade)
		        .build();
}

3. 롬복으로 빌더 패턴 적용

package kr.pe.playdata.domain;

import lombok.Builder;
import lombok.Getter;

@Getter //Getter 생성 
public class LombokPerson {

	private  String name;
	private  String grade;
	private  int age;
	
	@Builder // 생성자 만든 후 위에 @Build 어노테이션 적용 
	public LombokPerson(String name, String grade, int age) {
		this.name = name;
		this.grade = grade;
		this.age = age;
	}
}

참고 블로그 : http://yoonbumtae.com/?p=2565

단위테스트

하나의 모듈(하나의 기능 or 메소드)을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트
"~~ 기능이 실행되면 ~~한 결과가 나온다" 정도로 테스트를 진행한다.
참고 : 단위 테스트(Unit Test) 작성의 필요성

필요 라이브러리

  • JUnit : 자바 단위 테스트 위한 테스팅 프레임워크
    프로젝트 우클릭 => properties 클릭 => Java Build Path에서 Add Library => JUnit 선택
  • AssertJ : 자바 테스트를 위해 다양한 문법을 제공하고 직관적 테스트 흐름을 작성할 수 있도록 개발된 라이브러리(JUnit보다 test의도를 더 쉽게 파악할 수 있음)

given, when, then 패턴

  • 1개의 단위 테스트를 given, when, then 3단계로 나누어 처리하는 패턴
    - given(준비) : 어떤 데이터가 준비되었을 때
    • when(실행) : 어떤 함수를 실행하면
    • then(검증) : 어떤 결과가 나와야 한다.

단위 테스트 (빌더 패턴 적용)

import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

public class tttest {
	// 개발 기능이 정상인지 단순 확인하는 단위 Test 메소드
    @Test
    public void 빌더_테스트_1() {
    	
        //given
		String name = "jueun";
		int age = 24;
		String grade = "4";
       
       //when
		Person p1 = Person.builder()
		        .name(name)
		        .age(age)
		        .grade(grade)
		        .build();
        //then
        assertThat(p1.getGrade()).isEqualTo(grade);
        assertThat(p1.getAge()).isEqualTo(age);
        assertThat(p1.getName()).isEqualTo(name);
    }
}

성공(AssertJ에서 오류)

단위 테스트 (롬복 빌더 패턴 적용)

package kr.pe.playdata.domain;

import org.junit.jupiter.api.Test;

public class LombokPerTest {
    @Test
    public void 빌더_테스트_2() {
    	
        //given
		String name = "jueun";
		int age = 24;
		String grade = "4";
        
        //when
		LombokPerson p1 = LombokPerson.builder()
		        .name(name)
		        .age(age)
		        .grade(grade)
		        .build();
                
        //then
        assertThat(p1.getGrade()).isEqualTo(grade);
        assertThat(p1.getAge()).isEqualTo(age);
        assertThat(p1.getName()).isEqualTo(name);
                
    }
}

단위 테스트 결과


🎈 Reference

profile
과정은 힘들지만😨 성장은 즐겁습니다🎵

0개의 댓글