๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ค‘์š”ํ•œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์˜๋„๋Œ€๋กœ ์ž˜ ๋™์ž‘ํ•˜๊ณ  ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ์—†๋А๋‹ž ํ™•์ธํ•  ๋ชฉ์ ์œผ๋กœ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค. 

ํ˜„์žฌ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ ์‹ค๋ฌด์—์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์‚ฌ์šฉ์€ ๋งค์šฐ ์ค‘์š”ํ•ด์กŒ๋‹ค.

์ฝ”๋“œ์˜ ๋™์ž‘์„ ๊ฒ€์ฆํ•˜๊ณ , ์œ ์ง€๋ณด์ˆ˜์—ํ•˜๊ธฐ์— ๋งค์šฐ ์ข‹๊ณ , ๊ฐœ๋ฐœ์ž ์ž์ฒด๊ฐ€ ๋ฌด์—‡์„ ๋งŒ๋“ค๊ณ  ์žˆ๋Š”์ง€ ์ •ํ™•ํžˆ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉฐ, 

์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐœ๊ฒฌํ•ด ๋ถ€๋‹ด์„ ๋œ์–ด์ฃผ๋Š” ์žฅ์ ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

๋‚˜ ๋˜ํ•œ, ์‚ฌ์‹ค์ƒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ฒ˜์Œ ์ ‘ํ–ˆ์„ ๋•Œ๋Š” ์–ด๋ ต๊ธฐ๋„ ํ•˜๊ณ , ์ด๊ฒŒ ๊ตณ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ธ๊ฐ€? ์‹ถ์–ด ๋”ฑํžˆ ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. 

ํ•˜์ง€๋งŒ, ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ™•์‹คํžˆ ํฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋งŽ์€ ๋„์›€์ด ๋จ์„ ๋А๋ผ๊ณ  ๊ณต๋ถ€๋ฅผ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. 

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์ฃผ๋กœ V๋ชจ๋ธ์„ ๋”ฐ๋ผ ์ƒ๊ฐ ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

V๋ชจ๋ธ์€ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์‹œ๊ฐํ™”ํ•œ ๋ชจ๋ธ๋กœ ํ…Œ์ŠคํŠธ ๋‹จ๊ณ„๊ฐ€ ๊ฐœ๋ฐœ ๋‹จ๊ณ„๊ฐ€ ์ผ์น˜ํ•˜๋„๋ก ํ•˜๋Š” ๊ณผ์ •์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. (CS ์ง€์‹์ž„_์ •์ฒ˜๊ธฐ ์‹œํ—˜ ๋‚ด์šฉ!!)

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ๋‹จ์œ„ํ…Œ์ŠคํŠธ, ํ†ตํ•ฉํ…Œ์ŠคํŠธ, ์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ, ์‚ฌ์šฉ์ž์ธ์ˆ˜ ํ…Œ์ŠคํŠธ ๋“ฑ ๋‹ค์–‘ํ•œ ๋‹จ๊ณ„๋กœ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค. 

์ด๋Ÿฌํ•œ ํ…Œ์ŠคํŠธ๋“ค์€ ์ž…์ถœ๋ ฅ ๊ฐ’์„ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ์ธก๋ฉด์„ ๊ณ ๋ คํ•˜๊ฒŒ ๋˜๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ํ‰๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค. 

v๋ชจ๋ธ

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ž€? 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” test ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค. 

spring boot ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” test directory๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—๋Š” ๋‹ค์–‘ํ•œ ํŒจํ„ด์ด ์žˆ๋‹ค. 

๊ทธ ์ค‘, ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด์€ given - when - then ํŒจํ„ด์ด ์žˆ๋‹ค. 

  • Given ์€ ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ์ค€๋น„ํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค. 
  • When ์€ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค.
  • Then ์€ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค. 

์‚ฌ์‹ค ์ด๋ ‡๊ฒŒ ์„ค๋ช…ํ•ด๋„ ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค 

์˜ˆ๋ฅผ ๋“ค์–ด ์ƒˆ๋กœ์šด ๋ฉ”๋‰ด๋ฅผ ์ €์žฅํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ฒ ๋‹ค.

@DisplayName("์ƒˆ๋กœ์šด ๋ฉ”๋‰ด ์ €์žฅ") //ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์ด๋ฆ„ ์„ค์ •
@Test  //JUnit ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ์ž„์„ ์„ ์–ธํ•œ๋‹ค. 
public void saveMenuTest() {

//given : ๋ฉ”๋‰ด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ „์ฒ˜๋ฆฌ ๊ณผ์ •
final String name = "์นดํŽ˜๋ผ๋–ผ"; //์ƒˆ๋กœ ์ถ”๊ฐ€ํ•  ๋ฉ”๋‰ด์˜ ์ด๋ฆ„ ์„ค์ •
final int price = 1500; //์ƒˆ๋กœ ์ถ”๊ฐ€ํ•  ๋ฉ”๋‰ด์˜ ๊ฐ€๊ฒฉ์„ ์„ค์ •

fianl Menu caffeLatte = new Menu(name, price); //"์นดํŽ˜๋ผ๋–ผ" ๋ฉ”๋‰ด๋ฅผ ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™”์‹œํ‚ค๋Š” ๊ณผ์ •.

//when : ์‹ค์ œ ๋ฉ”๋‰ด ์ €์žฅ 
final long saveNum = menuService.save(caffeLatte); //๋ฉ”๋‰ด๋ฅผ ์ €์žฅํ•˜๊ณ  ์ €์žฅ๋œ ๋ฉ”๋‰ด์˜ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

//then : ๊ฒ€์ฆ
final Menu savedMenu = menuService.findById(saveId).get(); //์ €์žฅ๋œ ๋ฉ”๋‰ด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ฐ€์ ธ์˜จ๋‹ค.
assertThat(savedMenu.getName()).isEqualTo(name); //์ €์žฅ๋œ ๋ฉ”๋‰ด์˜ ์ด๋ฆ„์ด ์˜๋„ํ•œ ๊ฒฐ๊ณผ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. -> asserthat()์€ ๊ฒ€์ฆ์„ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ์ด๋‹ค. 
assertThat(savedMenu.getPrice()).isEqualTo(price); //์ €์žฅ๋œ ๋ฉ”๋‰ด์˜ ๊ฐ€๊ฒฉ์ด ์˜๋„ํ•œ ๊ฒฐ๊ณผ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
}

 

์ด๊ฑด ๋‹จ์ˆœํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์˜ˆ์ œ์ด๋‹ค. 

given์ ˆ์„ ํ†ตํ•ด ๋ฉ”๋‰ด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ค€๋น„ํ•˜๊ณ , when ์ ˆ์„ ํ†ตํ•ด ์‹ค์ œ๋กœ ๋ฉ”๋‰ด๋ฅผ ์ €์žฅํ•˜๊ณ , then์ ˆ์„ ํ†ตํ•ด ๋ฉ”๋‰ด๊ฐ€ ์ž˜ ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์Šคํ”„๋ง ๋ถ€ํŠธ์™€ ํ…Œ์ŠคํŠธ ๋„๊ตฌ

์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ์™€ ์• ๋„ˆํ…Œ์ด์…˜์„ ์ œ๊ณตํ•œ๋‹ค. 

springboot-starter-test ์Šคํƒ€ํ„ฐ์— ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๋„๊ตฌ๊ฐ€ ๋ชจ์—ฌ ์žˆ์–ด์„œ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.  

์Šคํ”„๋ง ๋ถ€ํŠธ ์Šคํƒ€ํ„ฐ ํ…Œ์ŠคํŠธ ๋ชฉ๋ก

  • JUnit : ์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์šฉ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ
  • AssertJ : ๊ฒ€์ฆ๋ฌธ์ธ assertion์„ ์ž‘์„ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • Spring Test & Spring Boot Test : ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ง€์›
  • Hamcrest : ํ‘œํ˜„์‹์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” Matcher ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • Mockito : ํ…Œ์ŠคํŠธ์— ์‚ฌ์šฉํ•  ๊ฐ€์งœ ๊ฐ์ฒด์ธ ๋ชฉ ๊ฐ์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ณ , ๊ด€๋ฆฌ,๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ง€์›ํ•˜๋Š” ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ
  • JsonPath : JSON ๋ฐ์ดํ„ฐ์—์„œ ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์„ ํƒํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • JSONassert : JSON์šฉ assertion ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ด ์ค‘ JUnit๊ณผ AssertJ๋ฅผ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค. 

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ด ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ํšจ์œจ์ ์ธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. 

 

๋” ์ž์„ธํ•œ ์Šคํƒ€ํ„ฐ ํ…Œ์ŠคํŠธ ๋„๊ตฌ์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค์Œ ๊ธ€์„ ํ†ตํ•ด ๋‹ค๋ค„๋ณผ ์˜ˆ์ •์ด๋‹ค.

 

๋Œ“๊ธ€