🌈 [Section3] 11. [ Spring MVC ] ν…ŒμŠ€νŒ… 2

ν˜„μ£ΌΒ·2022λ…„ 11μ›” 13일
0

bootcamp

λͺ©λ‘ 보기
51/71

πŸ“• 였늘 배운 λ‚΄μš©!

  • Mockitoλ₯Ό μ‚¬μš©ν•œ ν…ŒμŠ€νŒ… 방법

✏️ Mock

  • not real, but intended to be very similar to a real situation, substance etc
    ( 말 κ·ΈλŒ€λ‘œ, μ§„μ§œλŠ” μ•„λ‹ˆμ§€λ§Œ μ§„μ§œμ™€ μ•„μ£Ό λΉ„μŠ·ν•œ κ°€μ§œ)

βœ”οΈ λͺ©μ—… (Mock-up)

  • μ‹€μ œ μ œν’ˆμ΄ λ‚˜μ˜€κΈ° 전에 λ‚΄λΆ€μ μœΌλ‘œ μ‚¬μš©ν•˜κΈ° μœ„ν•œ λͺ¨ν˜•(κ°€μ§œ) μ œν’ˆ
  • ν…ŒμŠ€νŠΈ μ„Έκ³„μ—μ„œλŠ” κ°€μ§œ 객체λ₯Ό 의미

βœ”οΈ Mocking

  • λ‹¨μœ„ ν…ŒμŠ€νŠΈλ‚˜ 슬라이슀 ν…ŒμŠ€νŠΈ 등에 Mock 객체λ₯Ό μ‚¬μš©ν•˜λŠ” 것

βœ” ν…ŒμŠ€νŠΈμ—μ„œ Mock 객체λ₯Ό μ‚¬μš©ν•˜λŠ” 이유

Mock 객체λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  MemberController ν…ŒμŠ€νŠΈ 쀑 postMember ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν•œλ‹€κ³  ν•˜λ©΄ 이의 흐름은 μ•„λž˜μ™€ 같을 κ²ƒμž„

  1. MemberControllerTest 클래슀 λ‚΄μ˜ postMemberTest()
  2. MemberController 클래슀 λ‚΄μ˜ postMember()
  3. MemberService 클래슀 λ‚΄μ˜ createMember()
  4. MemberRepository μΈν„°νŽ˜μ΄μŠ€ λ‚΄μ˜ save()
  5. H2
  6. λ‹€μ‹œ λ°˜λŒ€λ‘œ μ­‰ λŒμ•„κ°€μ„œ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— 도달

But, μ΄λŠ” 거의 λͺ¨λ“  계측을 돌고 였기 λ•Œλ¬Έμ— μ™„μ „ν•œ 슬라이슀 ν…ŒμŠ€νŠΈκ°€ μ•„λ‹Œ, ν†΅ν•©ν…ŒμŠ€νŠΈμ— κ°€κΉŒμ›€

➜ ❗ Mock 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€λ₯Έ 계측과 λ‹¨μ ˆμ„ μ‹œμΌœμ£Όμ–΄
이 과정을 쀄여주고 슬라이슀 ν…ŒμŠ€νŠΈλ₯Ό μ μš©ν•  수 μžˆλ„λ‘ ν•  것 !

  • Mock 객체λ₯Ό μ‚¬μš©ν•œ MemberController ν…ŒμŠ€νŠΈ 쀑 postMember ν…ŒμŠ€νŠΈμ˜ 진행 흐름은
    1. MemberControllerTest 클래슀 λ‚΄μ˜ postMemberTest()
    2. MemberController 클래슀 λ‚΄μ˜ postMember()
    3. MockMemberService 클래슀 λ‚΄μ˜ createMember()
    4. λ‹€μ‹œ λ°˜λŒ€λ‘œ μ­‰ λŒμ•„κ°€μ„œ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— 도달

✏️ Mockito

  • Mock 객체λ₯Ό μƒμ„±ν•˜κ³  ν•΄λ‹Ή Mock 객체가 μ§„μ§œμ²˜λŸΌ λ™μž‘ν•˜κ²Œ ν•˜λŠ” κΈ°λŠ₯을 ν•˜λŠ” Mocking framework(λ˜λŠ” 라이브러리)

  • Mockito의 Mocking κΈ°λŠ₯을 μ΄μš©ν•΄μ„œ ν…ŒμŠ€νŠΈν•˜κ³ μž ν•˜λŠ” λŒ€μƒμ—μ„œ λ‹€λ₯Έ μ˜μ—­(λ‹€λ₯Έ 계측 λ˜λŠ” μ™ΈλΆ€ 톡신이 ν•„μš”ν•œ μ„œλΉ„μŠ€ λ“±)을 λ‹¨μ ˆμ‹œμΌœ μ˜€λ‘œμ§€ ν…ŒμŠ€νŠΈ λŒ€μƒμ—λ§Œ 집쀑할 수 있게 함

[μ°Έκ³ ] https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html
https://javacan.tistory.com/entry/MocktestUsingMockito
[Mockito λ©”μ„œλ“œλ“€ μ°Έκ³ ] https://jdm.kr/blog/222

[Mockito 지원 Matchers μ°Έκ³ ] https://www.javadoc.io/doc/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html

βœ” Mockito 지원 Stubbing λ©”μ„œλ“œ

  • given(Mock 객체 클래슀λͺ….λ©”μ„œλ“œλͺ…(Mockito.any(κ°μ²΄νƒ€μž….class))).willReturn(객체λͺ…)
    ➜ Mock 객체인 ν•΄λ‹Ή 클래슀둜 ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ μ •μ˜ν•¨
    ➜ Mockito.any()λŠ” μ–΄λ–€ νƒ€μž…μœΌλ‘œ ν˜ΈμΆœλ μ§€ 지정
    ➜ .willReturn()은 μœ„μ˜ ν•΄λ‹Ή λ©”μ„œλ“œκ°€ 리턴할 Stub 데이터

βœ”οΈ Stubbing

  • ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄μ„œ Mock 객체가 항상 μΌμ •ν•œ λ™μž‘μ„ ν•˜λ„λ‘ μ§€μ •ν•˜λŠ” 것

βœ”οΈ Stub

  • ν˜ΈμΆœμ‹œ 항상 정해진 행동을 ν•˜κ±°λ‚˜ 정해진 데이터λ₯Ό λŒλ €μ£ΌλŠ” μ»΄ν¬λ„ŒνŠΈ
  • 주둜 ν…ŒμŠ€νŠΈμ—μ„œ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— Test Stub이라고 함

βœ” 슬라이슀 ν…ŒμŠ€νŠΈμ— Mockito 적용

1. MemberController의 postMember() ν…ŒμŠ€νŠΈμ— Mockito 적용

  • @MockBean μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ κ°€μ§œ 객체둜 λ§Œλ“€ Service 클래슀 지정 ν›„, ν•„λ“œμ— DI

[@MockBean μ°Έκ³ ] https://howtodoinjava.com/spring-boot2/testing/spring-mockbean-annotation/

  • @Autowired μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ Dto 클래슀λ₯Ό κ°μ‹Έμ„œ μš”μ²­/응닡을 μ²˜λ¦¬ν•  mapper 클래슀λ₯Ό ν•„λ“œμ— DI

Ex. MemberControllerMockTest 클래슀의 postMemberTest()λ₯Ό ν˜ΈμΆœν•˜μ—¬ μ‹€ν–‰ν•œ κ²°κ³Ό

➜ MockMemberService의 createMember() λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜λ―€λ‘œ, 데이터 μ•‘μ„ΈμŠ€ 계측μͺ½μ˜ λ‘œμ§μ€ 싀행이 λ˜μ§€ μ•ŠμŒ

➜ MockMemberService ν΄λž˜μŠ€λŠ” μš°λ¦¬κ°€ ν…ŒμŠ€νŠΈν•˜κ³ μž ν•˜λŠ” Controller의 ν…ŒμŠ€νŠΈμ— 집쀑할 수 μžˆλ„λ‘ λ‹€λ₯Έ κ³„μΈ΅κ³Όμ˜ 연동을 λŠμ–΄μ£ΌλŠ” 역할을 ν•˜λŠ” 것

2. MemberService의 createMember() ν…ŒμŠ€νŠΈμ— Mockito 적용

  • 클래슀 λ ˆλ²¨μ— @ExtendWith(MockitoExtension.class) 적용
    ➜ Spring을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , Junitμ—μ„œ Mockito의 κΈ°λŠ₯을 μ‚¬μš©ν•˜κ² λ‹€λŠ” 의미

  • @Mock μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ Mock 객체둜 λ§Œλ“€ Repository 클래슀 지정 ν›„, ν•„λ“œμ— DI

  • @InjectMocks μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ Mock 객체λ₯Ό μ£Όμž…ν•  Service 클래슀 지정 ν›„, ν•„λ“œμ— DI


✏️ TDD (Test Driven Development)

  • ν…ŒμŠ€νŠΈ 주도 개발

  • 'ν…ŒμŠ€νŠΈλ₯Ό λ¨Όμ € ν•˜κ³  κ΅¬ν˜„μ€ κ·Έ λ‹€μŒμ— ν•œλ‹€'
    ( ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ λ¨Όμ € μž‘μ„± ν›„, 그에 λ§žλŠ” μœ νš¨μ„± 검증 λ‘œμ§μ΄λ‚˜ ν™œμš©ν•  λ©”μ„œλ“œ / ν΄λž˜μŠ€λ“€μ„ μž‘μ„±ν•˜μ—¬ failed ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό passed둜 λ°”κΏ”μ£ΌλŠ” 것 )

βœ”οΈ DDD (Domain Driven Design)
도메인 μ€‘μ‹¬μ˜ 섀계 기법

[μ°Έκ³ ]
https://www.simform.com/blog/what-is-tdd/
https://ko.wikipedia.org/wiki/%ED%85%8C%EC%8A%A4%ED%8A%B8_%EC%A3%BC%EB%8F%84_%EA%B0%9C%EB%B0%9C

βœ” TDD νŠΉμ§•

  • λͺ¨λ“  쑰건에 λ§Œμ‘±ν•˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό λ¨Όμ € μ§„ν–‰ν•œ λ’€, 쑰건에 λ§Œμ‘±ν•˜μ§€ μ•ŠλŠ” ν…ŒμŠ€νŠΈλ₯Ό λ‹¨κ³„μ μœΌλ‘œ μ§„ν–‰ν•˜λ©΄μ„œ μ‹€νŒ¨ν•˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό μ μ§„μ μœΌλ‘œ μ„±κ³΅μ‹œμΌœ 감

  • μ‹€ν–‰ κ²°κ³Όκ°€ failed인 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό μ§€μ†μ μœΌλ‘œ 그리고 λ‹¨κ³„μ μœΌλ‘œ μˆ˜μ •ν•˜λ©΄μ„œ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μ‹€ν–‰ κ²°κ³Όκ°€ passedκ°€ λ˜λ„λ‘ λ§Œλ“¦

  • ν…ŒμŠ€νŠΈκ°€ passed 될 만큼의 μ½”λ“œλ§Œ μš°μ„  μž‘μ„±

  • μ‹€νŒ¨ν•˜λŠ” ν…ŒμŠ€νŠΈ β†’ μ‹€νŒ¨ν•˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό 성곡할 만큼의 κΈ°λŠ₯ κ΅¬ν˜„ β†’ μ„±κ³΅ν•˜λŠ” ν…ŒμŠ€νŠΈ β†’ λ¦¬νŒ©ν† λ§ β†’ μ‹€νŒ¨ν•˜λŠ” ν…ŒμŠ€νŠΈμ™€ μ„±κ³΅ν•˜λŠ” ν…ŒμŠ€νŠΈ ν™•μΈμ˜ 흐름 반볡

βœ” TDD μž₯점

  • ν…ŒμŠ€νŠΈλ₯Ό 톡과할 만큼의 기증을 κ΅¬ν˜„
    ➜ ν•œλ²ˆμ— λ„ˆλ¬΄ λ§Žμ€ κΈ°λŠ₯ κ΅¬ν˜„ ν•„μš” X

  • ν…ŒμŠ€νŠΈμ˜ μ½”λ“œκ°€ μΆ”κ°€λ˜λ©΄μ„œ 검증 λ²”μœ„κ°€ λ„“μ–΄μ§ˆ 수둝, κΈ°λŠ₯ κ΅¬ν˜„λ„ μ μ§„μ μœΌλ‘œ μ™„μ„±
    ➜ λ‹¨μˆœν•œ κΈ°λŠ₯ -> λ³΅μž‘ν•œ κΈ°λŠ₯으둜 ν™•μž₯λ˜λ©΄μ„œ 검증 빼먹지 μ•Šκ³  κ°€λŠ₯

  • λ¦¬νŒ©ν† λ§ν•  뢀뢄이 생기면 κ·Έλ•Œ κ·Έλ•Œ λ¦¬νŒ©ν† λ§ κ°€λŠ₯
    ➜ λ¦¬νŒ©ν† λ§μ˜ λΉ„μš© μƒλŒ€μ μœΌλ‘œ 적어짐

  • 항상 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€κ°€ μ‘΄μž¬ν•˜λ―€λ‘œ μ½”λ“œ μˆ˜μ •μ— λŒ€ν•œ 심리적 λΆˆμ•ˆκ°μ΄ 쀄어듦

  • λ¦¬νŒ©ν† λ§μœΌλ‘œ κΎΈμ€€νžˆ μ½”λ“œλ₯Ό κ°œμ„ ν•˜λ―€λ‘œ μ½”λ“œμ˜ ν’ˆμ§ˆμ„ 일정뢀뢄 μœ μ§€ κ°€λŠ₯

  • μ½”λ“œ μˆ˜μ • 이후, λ°”λ‘œ ν…ŒμŠ€νŠΈ κ°€λŠ₯
    ➜ μ½”λ“œ μˆ˜μ • 결과에 λŒ€ν•œ λΉ λ₯Έ ν”Όλ“œλ°±

βœ” TDD 단점

  • 아직 TDD 방식이 μ΅μˆ™μΉ˜ μ•Šλ‹€λŠ” 점

  • ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±μ„ μ‹«μ–΄ν•˜λŠ” μ‚¬λžŒλ“€μ—κ²ŒλŠ” 뢀정적인 방식
    But, μ‹€λ¬΄μ—μ„œλŠ” κ²°κ΅­ κΌ­ 해야함

  • νŒ€ λ‹¨μœ„λ‘œ 개발이 μ§„ν–‰λ˜λŠ” μ‹€λ¬΄μ—μ„œλŠ” νŒ€μ›λ“€ κ°„ 사전 ν˜‘μ˜κ°€ λ˜μ–΄μ•Όν•¨


😜 μ‹€μŠ΅

  • projects - be-template-testing-mock
  • git - be-homework-testing-mock

But, 이번 μ‹€μŠ΅μ€ Mapperλ₯Ό ν…ŒμŠ€νŠΈ λŒ€μƒμœΌλ‘œ λ³΄κ³ μžˆμ§€ μ•ŠμŒ !

상황에 따라 Mapper도 맀핑이 잘 λ˜λŠ”μ§€ ν…ŒμŠ€νŠΈ κ°€λŠ₯ !

......................................................................................................................................................................................................

βœ”οΈ UriComponentsBuilder 클래슀λ₯Ό μ΄μš©ν•œ UriComponents μΈμŠ€ν„΄μŠ€ 생성 방법

μ›λž˜λŠ” path 둜 url을 지정할 λ•Œ,

mockMvc.perform(get("/v11/members/"+member.getMemberId())); 이런 μ‹μœΌλ‘œ μ§€μ •ν•˜μ˜€μ—ˆλŠ”λ°

μ € μ•ˆμ— 직접 넣지 μ•Šκ³ 

URI uri = UriComponentsBuilder.newInstance().path("/v11/members").build().toUri();

μœ„μ™€ 같이 UriComponentsBuilder 클래슀λ₯Ό μ΄μš©ν•˜μ—¬ 생성해쀄 수 μžˆλ‹€ !

이 경우 pathμ—λŠ” κ°„λ‹¨νžˆ

mockMvc.perform(get(uri)); μ΄λ ‡κ²Œλ§Œ λ„£μ–΄μ£Όλ©΄ λ°”λ‘œ 생성 κ°€λŠ₯ !

[μ°Έκ³ ] https://blog.naver.com/PostView.naver?blogId=aservmz&logNo=222322019981


🌈 λŠλ‚€μ 

Mockitoκ°€ λ“€μ–΄κ°€λ‹ˆκΉŒ μ’€ μ–΄λ €μ›Œμ‘Œλ‹€γ… γ… 
사싀 νŽ˜μ–΄μ™€ μ‹€μŠ΅ν•˜λ©΄μ„œ 1μ‹œκ°„ λ°˜λ™μ•ˆ μ—λŸ¬λ“€μ„ ν•΄κ²°ν•˜λŠλΌ 2개의 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ°–μ— μ™„λ£Œν•˜μ§€ λͺ»ν–ˆλ‹€.
λ™μž‘ 방식과 λ™μž‘ μˆœμ„œ, ꡬ성 등을 잘 μ΅ν˜€μ„œ λ‹€λ₯Έ μ½”λ“œλ₯Ό μ°Έκ³ ν•˜μ§€ μ•Šκ³ λ„ λ°”λ‘œλ°”λ‘œ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό μž‘μ„±ν•  수 μžˆλ„λ‘ 해야지

0개의 λŒ“κΈ€