Spring๐Ÿƒ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ(2)

wannaDevelopIt 2023. 1. 26. 20:11
728x90

์ถœ์ฒ˜ : ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„

 

์œ ๋‹›(๋‹จ์œ„) ํ…Œ์ŠคํŠธ : ๋ฉ”์„œ๋“œ ๋‹จ์œ„๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ : ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ „์ฒด ๋™์ž‘์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ์ˆ˜ํ–‰

 

F.I.R.S.T ์›์น™

  • Fast : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ๋นจ๋ผ์•ผ ํ•œ๋‹ค.
  • Independent : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ๊ฐ๊ฐ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์—ฐ๊ด€๋˜์ง€ ์•Š๊ณ , ๊ณ ๋ฆฝ๋˜์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰ ๋…๋ฆฝ์  ์ด์–ด์•ผ ํ•œ๋‹ค.
  • Repeatable : ๋‹จ์œ„ํ…Œ์ŠคํŠธ๋Š” ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค. ๋ฐ˜๋ณต์ ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹œํ–‰ํ•ด๋„, ๊ฒฐ๊ณผ๋Š” ๊ฐ™์•„์•ผ ํ•œ๋‹ค.
  • Self-validating : ์ž์ฒด์ ์œผ๋กœ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๊ฐ€ ๋„์ถœ๋˜์•ผํ•œ๋‹ค. (๊ฐœ๋ฐœ์ž๊ฐ€ print ์ฐ์–ด์„œ ๋น„๊ตํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๊ณ  ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰๋˜๋ฉฐ ์„ฑ๊ณต/์‹คํŒจ ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ)
  • Timely : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ์‹ค์ œ ์ฝ”๋“œ๋ณด๋‹ค ๋จผ์ € ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค. (TDD์ผ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น)

Given-When-Then ํŒจํ„ด

  • Given : ํ…Œ์ŠคํŠธ์— ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ฑฐ๋‚˜ Mock ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ํŠน์ • ์ƒํ™ฉ์— ๋Œ€ํ•œ ํ–‰๋™์„ ์ •์˜
  • When: ์‹ค์ œ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉฐ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•œ ๊ฒฐ๊ณผ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค.
  • Then: When ๋‹จ๊ณ„์—์„œ ๋‚˜์˜จ ๊ฒฐ๊ณผ๊ฐ’์„ ๊ฒ€์ฆํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰

Junit + Mockito

Junit : ์ž๋ฐ”์˜ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ

Mockito : Mock ๊ฐ์ฒด ์ƒ์„ฑ, ๊ด€๋ฆฌ, ๊ฒ€์ฆ ํ”„๋ ˆ์ž„์›Œํฌ

~ ๊ฐ€์งœ ๊ฐ์ฒด์˜ ์˜์กด์„ฑ ์ฃผ์ž…์„ ์œ„ํ•ด ํ•„์š”ํ•œ ์–ด๋…ธํ…Œ์ด์…˜

@Mock : Mock ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ๋ฐ˜ํ™˜ ์–ด๋…ธํ…Œ์ด์…˜

@Spy : Stubํ•˜์ง€ ์•Š์€ ๋ฉ”์†Œ๋“œ(๊ฐ€์งœ ๋ฉ”์†Œ๋“œ๊ฐ€ ์•„๋‹Œ)๋Š” ์›๋ณธ ๋ฉ”์†Œ๋“œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜

@InjectMocks : @Mock ๋˜๋Š” @Spy๋กœ ์ƒ์„ฑ๋œ ๊ฐ€์งœ ๊ฐ์ฒด ์ž๋™ ์ฃผ์ž… ์–ด๋…ธํ…Œ์ด์…˜

 

ex) UserController ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, @Mock ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๊ฐ€์งœ UserService๋ฅผ ๋งŒ๋“ค๊ณ , @InjectMocks๋ฅผ ํ†ตํ•ด UserController์— ์ด๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค

 

@ExtendWith(MockitoExtension.class) : Junit๊ณผ Mockito๋ฅผ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜

@DisplayName(" ") : ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ ๋ผ๋ฒจ๋ง ์–ด๋…ธํ…Œ์ด์…˜

 

Junit์˜ ์ƒ๋ช…์ฃผ๊ธฐ

ํ…Œ์ŠคํŠธ ์ˆœ์„œ์— ๊ด€์—ฌํ•˜๊ฒŒ ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜

@BeforeAll : ํ…Œ์ŠคํŠธ ์‹œ์ž‘ ์ „ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ

@BeforeEach : ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ

@AfterAll : ํ…Œ์ŠคํŠธ ์ข…๋ฃŒ ์‹œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ

@AfterEach : ๊ฐ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ ์ข…๋ฃŒ ์‹œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ

 

์ˆ˜์—… ํฌ์ธํŠธ

-> ๋ฉ”์„œ๋“œ ๋‚ด ์ข…์†์„ฑ ๊ฐ์ฒด๋Š” Mockingํ•ด ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๋งŒ์„ ๋ณด๋Š” ๊ฒƒ์ด๋‹ค.

ex) ์„œ๋น„์Šค ๋‹จ์œ„ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, DB ๊ฒ€์ƒ‰ ๋“ฑ์€ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค

-> ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†๋Š” ๋ฉ”์„œ๋“œ๋Š” ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

-> Then ๋‹จ๊ณ„์—์„œ๋Š” ์ฃผ๋กœ assert ๋ฌธ์„ ์‚ฌ์šฉํ•œ๋‹ค.

-> HttpServletResponse๋„ ํ•ด๋‹นํ•˜๋Š” Mock ๊ฐ์ฒด(MockHttpServletResponse ํƒ€์ž…)๋ฅผ ์ƒ์„ฑํ•ด ์ธ์ž ๊ฐ’์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค

 

01.30

ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ์ƒ์„ฑ - ์„œ๋ฒ„ ๊ตฌ๋™๋ฐฉ๋ฒ• ์„ ํƒ(@ExtendWtih ๋“ฑ) - ํ•„๋“œ ์ƒ์„ฑ + Mocking - ๋ฉ”์„œ๋“œ ์ž‘์„ฑ (when - given - then)- ํ…Œ์ŠคํŠธ

 

๊ฐ•์˜์—์„œ ์‚ฌ์šฉํ•œ MockMvcBuilders ํด๋ž˜์Šค

https://donghyeon.dev/spring/2019/03/28/Spring-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9C%84%ED%95%9C-MockMvc/

์ €๋ฒˆ ์‹ค์Šต ๋•Œ ๋ณธ @SpringBootTest + MockMvc + @TestConstructor

https://gaemi606.tistory.com/entry/JUnit-5-ExtendWith-MockMvc-TestConstructor

* ์ปจํŠธ๋กค๋Ÿฌ ๋ ˆ์ด์–ด์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ๊ทธ ๋กœ์ง์ด ๋ณต์žกํ•˜์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŠธ ํ•„์š”์„ฑ์ด ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ๋น„ํ•ด ํฌ์ง€ ์•Š์•„ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์˜ ํ•„์š”์„ฑ์ด ๋–จ์–ด์ง„๋‹ค & ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์˜ ์ปจํŠธ๋กค๋Ÿฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์™€ ์œ ์‚ฌํ•œ ์ ์ด ๋งŽ๋‹ค

~ ํ†ตํ•ฉํ…Œ์ŠคํŠธ, ํฌ์ŠคํŠธ๋งจ์„ ํ†ตํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ๋ณด๋‹ค ๋ฐ”๋žŒ์งํ•˜๋‹ค

 

๋ ˆํฌ์ง€ํ† ๋ฆฌ ํ…Œ์ŠคํŠธ : ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ๋Š” ์ด๋ฏธ ์™„์„ฑ๋˜์–ด ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธํ•  ํ•„์š” ์—†๋‹ค

Mocking ํ•  ํ•„์š” ์—†๋‹ค

 

728x90