Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Getter and Setter / Optional.ofNullable / Assertions / Extract Method 생성 / AfterEach / assertThrows

Table of contents

  1. 클래슀 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜ μž…λ ₯ 및 좜λ ₯ λ©”μ„œλ“œ κ΅¬ν˜„ν•˜κΈ°
  2. Optional 을 μ‚¬μš©ν•˜λŠ” 이유
  3. Test Case μž‘μ„±
  4. AfterEach
  5. Extract Method 생성
  6. assertThrows

클래슀 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜ μž…λ ₯ 및 좜λ ₯ λ©”μ„œλ“œ κ΅¬ν˜„ν•˜κΈ°


image-20221018180104514

μœ„μ™€ 같은 Member ν΄λž˜μŠ€κ°€ μžˆμ„ λ•Œ, 각 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ— 데이터 값을 μ €μž₯ν•˜κ³  λ°˜ν™˜ν•˜λŠ” get κ³Ό set λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법은 맀우 κ°„λ‹¨ν•˜λ‹€.

μœˆλ„μš° κΈ°μ€€ 인텔리 제이 단좕킀 ctrl + shift + n 을 μž…λ ₯ν•˜κ³  Action λΆ€λΆ„μ—μ„œ getter and setter λ₯Ό κ²€μƒ‰ν•˜λ©΄ λœλ‹€.

image-20221018180156346

image-20221018180217568

get, set λ©”μ„œλ“œλ₯Ό 생성할 λ³€μˆ˜λ₯Ό μ„ νƒν•œ ν›„ ok λ²„νŠΌμ„ λˆ„λ₯΄λ©΄

image-20221018180234985

이와 같이 μžλ™μœΌλ‘œ μƒμ„±λœλ‹€!


Optional 을 μ‚¬μš©ν•˜λŠ” 이유


image-20221018180301802

λ¨Όμ €, νšŒμ› 관리λ₯Ό μœ„ν•œ 클래슀λ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œλ“€μ΄ μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.

findById() 와 findByName() λ©”μ„œλ“œλŠ” Optional<Member> 둜 λ°˜ν™˜μ΄ λ˜κ²Œλ” μž‘μ„±μ΄ λ˜μ–΄μžˆλ‹€.

Optional<T> λŠ” 지넀릭 클래슀둜 β€˜T νƒ€μž…μ˜ 객체’λ₯Ό κ°μ‹ΈλŠ” 래퍼 ν΄λž˜μŠ€μ΄λ‹€.

Optional νƒ€μž…μ˜ κ°μ²΄μ—λŠ” λͺ¨λ“  νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜λ₯Ό 담을 수 μžˆλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄, μ΅œμ’… μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό Optional 객체에 λ‹΄μ•„μ„œ λ°˜ν™˜μ„ ν•˜λŠ”λ°, 이처럼 객체에 λ‹΄μ•„μ„œ λ°˜ν™˜μ„ ν•˜λ©΄ λ°˜ν™˜λœ κ²°κ³Όκ°€ null인지 맀번 if문으둜 μ²΄ν¬ν•˜λŠ” λŒ€μ‹ 

Optional에 μ •μ˜λœ λ©”μ„œλ“œλ₯Ό ν†΅ν•΄μ„œ κ°„λ‹¨νžˆ μ²˜λ¦¬ν•  수 μžˆμ–΄ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ” κ°„κ²°ν•˜κ³  μ•ˆμ „ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

즉, κ°„μ ‘μ μœΌλ‘œ Null을 λ‹€λ£° 수 μžˆλ‹€.

κ΅¬ν˜„λΆ€λ₯Ό μ‚΄νŽ΄λ³΄μž.

image-20221018180316899

λ°˜ν™˜ν•  λ•Œ, κ·Έλƒ₯ return store.get(id); μ˜€λ‹€λ©΄ null 값이 λ°˜ν™˜λ˜μ—ˆμ„ λ•Œ μ—λŸ¬κ°€ λ°œμƒν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ, μœ„ μ½”λ“œμ™€ 같이 Optional<Member> 둜 λ°˜ν™˜λ˜λŠ” κ²½μš°μ—λŠ” μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

Optional.ofNullable() λ©”μ„œλ“œλ₯Ό ν™œμš©ν•΄μ•Όν•œλ‹€.

findById λŠ” idλ₯Ό ν†΅ν•΄μ„œ Member 객체λ₯Ό κΊΌλ‚΄μ˜€λŠ” λ©”μ„œλ“œμ΄κ³  store 의 경우 idκ°€ ν‚€κ°’μœΌλ‘œ μ§€μ •λ˜μ–΄μžˆμœΌλ―€λ‘œ

store.get(id) λ₯Ό ν†΅ν•΄μ„œ ν•΄λ‹Ή id에 μ†ν•˜λŠ” member 객체λ₯Ό 뢈러였고 이λ₯Ό Optional.ofNullable둜 감싸주면 λœλ‹€!

image-20221018180338387

findByName의 경우 약간은 λ³΅μž‘ν•˜λ‹€.

λ¨Όμ € store.values()λ₯Ό 톡해 store에 μ €μž₯된 λͺ¨λ“  member 객체λ₯Ό λΆˆλŸ¬μ˜¨λ‹€.

κ·Έ λ‹€μŒ, filter() λ©”μ„œλ“œλ₯Ό μ“°κΈ° μœ„ν•΄μ„œ .stream() 을 λΆ™μ—¬μ€€λ‹€.

.filter(쑰건 λžŒλ‹€μ‹) 은 ν•΄λ‹Ή 쑰건을 λ§Œμ‘±ν•˜μ§€ μ•ŠλŠ” 것듀을 κ±ΈλŸ¬μ€€λ‹€.

.filter(member -> member.getName().equals(name)) 을 ν†΅ν•΄μ„œ store에 μ €μž₯된 member의 name λ“€ 쀑 μž…λ ₯ν•œ nameκ³Ό 같은 member만 λ‚¨κ²Œλœλ‹€.

.findAny() λŠ” stream을 톡해 κ±ΈλŸ¬μ§„ 값을 μ•„λ¬΄κ±°λ‚˜ λ°˜ν™˜ν•˜λŠ”λ°, μœ„μ™€ 같은 경우 μ€‘λ³΅λœ 이름이 μ—†λ‹€κ³  κ°€μ •λ˜μ–΄ μžˆμœΌλ―€λ‘œ, μž…λ ₯ν•œ name을 가진 memberκ°€ μžˆλ‹€λ©΄ λ°˜ν™˜ν•  것이닀.


Test Case μž‘μ„±


μœˆλ„μš° 인텔리 제이의 경우

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό μž‘μ„±ν•˜κ³  싢은 class의 이름을 ν΄λ¦­ν•œ ν›„ ctrl + shift + t λ₯Ό μž…λ ₯ν•˜λ©΄ μ‰½κ²Œ test μ†ŒμŠ€νŒŒμΌμ„ 생성할 수 μžˆλ‹€.

image-20221018180424603

create New Test λ₯Ό ν΄λ¦­ν•˜λ©΄ λœλ‹€.

image-20221018180439521

그리고 ν…ŒμŠ€νŠΈλ₯Ό ν•΄λ³Ό λ©”μ„œλ“œλ₯Ό μ„ νƒν•œ ν›„ ok λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ μ†ŒμŠ€νŒŒμΌμ΄ μƒμ„±λœλ‹€.


ν…ŒμŠ€νŠΈ 파일 μž‘μ„± μ‹œ Assertions λ₯Ό 많이 μ‚¬μš©ν•˜κ²Œ λœλ‹€.

image-20221018180511334

Assertions의 μœ μš©ν•œ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ €λ©΄ import μ‹œμΌœμ•Ό ν•˜λŠ”λ°, junit이 μ•„λ‹Œ assertj λ₯Ό importν•΄μ•Όν•œλ‹€!

image-20221018180530350

Member result = repository.findById(member.getId()).get();

μ—μ„œ λ§ˆμ§€λ§‰μ— get()이 λΆ™λŠ” μ΄μœ λŠ”, findById의 λ°˜ν™˜κ°’μ΄ optional둜 감싸져 있기 λ•Œλ¬Έμ—, get() λ©”μ„œλ“œλ₯Ό 톡해 객체만 κΊΌλ‚Ό 수 μžˆλ‹€.

Assertions.assertThat(객체1).isEqualTo(객체2);

을 ν†΅ν•΄μ„œ 객체 1κ³Ό 객체 2 κ°€ 같은지 확인할 수 μžˆλ‹€.


AfterEach


ν…ŒμŠ€νŠΈλ₯Ό ν•˜λŠ” κ³Όμ •μ—μ„œ μ—¬λŸ¬ λ©”μ„œλ“œλ₯Ό ν•œλ²ˆμ— ν…ŒμŠ€νŠΈ ν•˜λ‹€λ³΄λ©΄, 데이터가 κ²Ήμ³μ„œ λ‹€λ₯Έ λ©”μ„œλ“œ ν…ŒμŠ€νŠΈμ— 영ν–₯을 쀄 수 μžˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ ν…ŒμŠ€νŠΈ λ©”μ„œλ“œκ°€ 끝날 λ•Œλ§ˆλ‹€ λ©”λͺ¨λ¦¬λ₯Ό λΉ„μ›Œμ£ΌλŠ” 것이 μ€‘μš”ν•˜λ‹€.

이 역할을 ν•  수 μžˆλŠ” μ—λ„ˆν…Œμ΄μ…˜μ΄ @AfterEach이닀.

image-20221018180601104

clearStrore() λ©”μ„œλ“œ μ•ˆμ—λŠ” κ°„λ‹¨ν•˜κ²Œ μ»¬λž™μ…˜ λ‚΄ 데이터λ₯Ό λͺ¨λ‘ μ§€μ›Œμ£ΌλŠ” store.clear(); λ₯Ό κ΅¬ν˜„ν•˜λ©΄ λœλ‹€.


Extract Method 생성


image-20221018180622550

.ifPresent() λ₯Ό ν†΅ν•΄μ„œ λ§Œμ•½ μ €μž₯ν•˜λ €λŠ” member의 name값이 이미 μ‘΄μž¬ν•˜λŠ” memberκ°€ repository에 이미 μ‘΄μž¬ν•œλ‹€λ©΄,

IllegalStateExceptionμ΄λΌλŠ” μ—λŸ¬λ₯Ό μΌμœΌν‚€κ³  β€œμ΄λ―Έ μ‘΄μž¬ν•˜λŠ” νšŒμ›μž…λ‹ˆλ‹€.” λΌλŠ” μ—λŸ¬λ©”μ„Έμ§€λ₯Ό λ„μš°κ²Œλ” κ΅¬ν˜„ν•˜μ˜€λ‹€.

λ˜ν•œ, μœ„ μ½”λ“œμ—μ„œ μ€‘λ³΅νšŒμ›μ€ κ°€μž…μ΄ μ•ˆλ˜λ„λ‘ ν•˜λŠ” 뢀뢄을 λ©”μ„œλ“œλ‘œμ¨ λ”°λ‘œ μΆ”μΆœν•˜λŠ” 단좕킀가 μžˆλ‹€.

image-20221018180636071

ν•΄λ‹Ή 뢀뢄을 λ“œλž˜κ·Έν•˜κ³ , μœˆλ„μš° κΈ°μ€€ ctrl + alt + shift + t λ₯Ό λ™μ‹œμ— λˆ„λ₯΄λ©΄ μœ„μ™€ 같은 창이 λ‚˜μ˜€κ³ 

Extract Methodλ₯Ό ν΄λ¦­ν•˜κ³  λ©”μ„œλ“œ 이름을 지정해주면 λœλ‹€.

image-20221018180711445

νŽΈν•˜κ²Œ λ©”μ„œλ“œλ‘œμ„œ μΆ”μΆœν•΄λ‚΄μ—ˆλ‹€.


assertThrows


image-20221018180728385

이전에, μ€‘λ³΅λœ νšŒμ›μ΄ μžˆλ‹€λ©΄, IllegalStateException μ—λŸ¬λ₯Ό μΌμœΌν‚€κ³  β€œμ΄λ―Έ μ‘΄μž¬ν•˜λŠ” νšŒμ›μž…λ‹ˆλ‹€.” λΌλŠ” μ—λŸ¬λ©”μ„Έμ§€λ₯Ό λ„μš°κ²Œλ” κ΅¬ν˜„ν•˜μ—ˆλ‹€.

assertThrowsλ₯Ό μ‚¬μš©ν•˜λ©΄ try-catch 문의 역할을 κ°„κ²°ν•˜κ²Œ ν•  수 μžˆλ‹€.

λ¨Όμ € IllegalStateException e = assertThrows(IllegalStateException .class, () -> memberService.join(member2)) λ₯Ό μ‚΄νŽ΄λ³΄μž.

member1κ³Ό member2의 이름은 λ™μΌν•˜κ³  member1은 이미 등둝이 λ˜μ–΄μžˆλŠ” 상황이닀.

assertThrows(μ—λŸ¬,쑰건식) 은 쑰건식이 μ‹€ν–‰λ˜μ—ˆμ„ λ•Œ μ—λŸ¬κ°€ λ°œμƒν•˜λŠ”μ§€ 확인해쀀닀.

즉, μœ„μ˜ κ²½μš°μ—λŠ” ()-> memberService.join(member2) λžŒλ‹€μ‹μ΄ μ‹€ν–‰λ˜μ—ˆμ„λ•Œ

IllegalStateException μ—λŸ¬κ°€ λ°œμƒν•˜λŠ”μ§€ 확인해쀀닀.

μ—λŸ¬λŠ” e에 μ €μž₯이 되고 getMessage()λ₯Ό 톡해 μ—λŸ¬λ©”μ„Έμ§€λ₯Ό μΆ”μΆœν•  수 있고

이λ₯Ό ν†΅ν•΄μ„œ μ€‘λ³΅λœ νšŒμ›μ΄ κ°€μž…μ„ μ‹œλ„ν•  경우, μ—λŸ¬κ°€ λ°œμƒν•˜λŠ”μ§€ μ•ˆν•˜λŠ”μ§€ 확인을 ν•  수 μžˆλ‹€.