Study/Next Step / / 2024. 2. 17. 15:21

[Next Step] ATDD, ํด๋ฆฐ ์ฝ”๋“œ with Spring 8๊ธฐ 2์ฃผ์ฐจ ๋ฆฌ๋ทฐ

๐ŸŽˆ ์ธ์ˆ˜ํ…Œ์ŠคํŠธ ๊ฒฉ๋ฆฌํ•˜๊ธฐ

์ธ์ˆ˜ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฒฉ๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. @Transactional ์–ด๋…ธํ…Œ์ด์…˜ ํ™œ์šฉ
  2. @DirtiesContext ์–ด๋…ธํ…Œ์ด์…˜ ํ™œ์šฉ
  3. @Sql ํ˜น์€ ์ฟผ๋ฆฌ ์ˆ˜ํ–‰
  4. ์ฝ”๋“œ ์ƒ์œผ๋กœ ํ…Œ์ด๋ธ” truncate

๋‚˜์˜ ๊ฒฝ์šฐ์—๋Š” 3๋ฒˆ์งธ ๋ฐฉ๋ฒ• ์ค‘ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  @interface๋กœ ์„ ์–ธํ•˜์—ฌ ํด๋ž˜์Šค๋‹จ์— ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ DB๋งˆ๋‹ค ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ, JPA์—์„œ @Embeddable๊ณผ ๊ฐ™์ด ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์ด ์ƒ๊ธฐ๋Š” ๊ฒฝ์šฐ๋„ ์ดˆ๊ธฐํ™”๋ฅผ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ด ๋ฐฉ๋ฒ•์„ ์„ ํƒํ–ˆ๋‹ค. 

 

@Transactional

  • RANDOM_PORT๋‚˜ DEFINED_PORT ์‚ฌ์šฉ ํ•  ๊ฒฝ์šฐ ์‹ค์ œ ์„œ๋ธ”๋ฆฟ ํ™˜๊ฒฝ์ด ์ œ๊ณต๋จ
  • HTTP Client์™€ Server๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๋™์ž‘
  • ๋”ฐ๋ผ์„œ @Transactional์„ ํ†ตํ•œ roll back์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Œ

 

@DirtiesContext

  • ํšจ๊ณผ์ ์ธ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰์„ ์œ„ํ•ด ์Šคํ”„๋ง์—์„œ๋Š” context caching ๊ธฐ๋Šฅ ์ง€์›
  • context caching์˜ ์กฐ๊ฑด์ด ๋นˆ์ด ์˜ค์—ผ(๋ณ€๊ฒฝ)๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
  • @DirtiesContext๋ฅผ ํ™œ์šฉํ•˜์—ฌ (๋นˆ์„ ์˜ค์—ผ์‹œ์ผœ) ์บ์‹œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ
  • ๋งค๋ฒˆ Context๋ฅผ ์ƒˆ๋กœ ๊ตฌ์„ฑํ•˜๋‹ค๋ณด๋‹ˆ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆผ

 

@Sql ํ˜น์€ ์ฟผ๋ฆฌ ์ˆ˜ํ–‰

  • ํ…Œ์ŠคํŠธ๊ฐ€ ์ˆ˜ํ–‰๋  ๋•Œ ๋งˆ๋‹ค ํ…Œ์ด๋ธ”๋“ค์„ truncate ์‹œํ‚ค๋Š” ์ฟผ๋ฆฌ ์ˆ˜ํ–‰
  • ์ปจํ…์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ๋„์šฐ๋Š” ๊ฒƒ ๋ณด๋‹ค ๋‚ฎ์€ ๋น„์šฉ
  • ํ…Œ์ด๋ธ”์ด ์ถ”๊ฐ€๋  ๋•Œ ๋งˆ๋‹ค ํ•ด๋‹น ์ฟผ๋ฆฌ ์ˆ˜์ •์ด ํ•„์š”

 

์ฝ”๋“œ ์ƒ์œผ๋กœ ํ…Œ์ด๋ธ” truncate

  • JPA ์‚ฌ์šฉ์‹œ EntityManager๋ฅผ ์ด์šฉํ•˜์—ฌ ํ…Œ์ด๋ธ” ์ด๋ฆ„ ์กฐํšŒ
  • ์•„๋‹Œ ๊ฒฝ์šฐ DataSource๋ฅผ ์ด์šฉํ•˜์—ฌ ํ…Œ์ด๋ธ” ์ด๋ฆ„ ์กฐํšŒ
  • ๊ฐ ํ…Œ์ด๋ธ”์„ truncate ์‹œ์ผœ์ฃผ๋Š” ์ฟผ๋ฆฌ ์ˆ˜ํ–‰
  • ํ…Œ์ด๋ธ” ์ƒํƒœ์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ์ดˆ๊ธฐํ™” ํ™˜๊ฒฝ ๊ตฌ์ถ• ๊ฐ€๋Šฅ

 

๐Ÿ˜Š ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

ํ…Œ์ŠคํŠธ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋ง ํ•  ๋•Œ๋Š” ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ์ด ์žˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ์˜ ์˜๋„๋ฅผ ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚ด์•ผ ํ•œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ๊ฐ€๋…์„ฑ์„ ์ฑ™๊ธธ ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€๋…์„ฑ์ด ์ข‹์ง€ ์•Š์€ ํ…Œ์ŠคํŠธ๋Š” ๋ฐฉ์น˜๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ณ , ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ˆ˜์ •ํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ€๋…์„ฑ์ด ์ข‹์œผ๋ฉด ํ•ด๋‹น ๊ธฐ๋Šฅ์˜ ์ŠคํŒฉ์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ๋„ ๋™์ผํ•˜๋‹ค.

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•ด๋ผ.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ ์ฝ”๋“œ๋‹ค. ์ฝ”๋“œ ์ž‘์„ฑ์‹œ ์ค‘๋ณต ๋‚ด์šฉ์ด ๋งŽ์ด ๋ฐœ์ƒํ•˜์—ฌ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด ์ค‘๋ณต์ œ๊ฑฐ๋ฅผ ํ•ด์•ผํ•œ๋‹ค.

๋ฉ”์†Œ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ , CRUD๋ฅผ ์ถ”์ƒํ™”ํ•˜๊ณ , Cucumber๋‚˜ JBehave์™€ ๊ฐ™์€ BDD ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘๋ณต ์ œ๊ฑฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์—์„œ ์žฌ์‚ฌ์šฉ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ์ฝ”๋“œ๋“ค์€ ๋ณ„๋„์˜ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ static ์„ ์–ธํ•˜์—ฌ ์‰ฝ๊ฒŒ ๋‹ค๋ฅธ๊ณณ์—์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜์—ฌ ์ผ๊ด€์„ฑ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  CRUD๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ์˜๋„๋ฅผ ๋“œ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๋ฉ”์„œ๋“œ๋ฅผ ํ•œ๊ธ€๋ช…์œผ๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ ์ฝ๊ธฐ ์‰ฌ์šด ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

โ“ ๋ชจ๋“  ์š”๊ตฌ์‚ฌํ•ญ์„ ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ• ๊นŒ?

์ด๋Š” ์ ˆ๋Œ€ ์•„๋‹ˆ๋‹ค. ๋น„ํšจ์œจ์ ์ด๋ฉฐ, ํ…Œ์ŠคํŠธ์˜ ์ˆ˜๊ฐ€ ๋งŽ์€๊ฒŒ ์ค‘์š”ํ•œ๊ฒŒ ์•„๋‹ˆ๋‹ค.

์„ฑ๊ณตํ•˜๋Š” ํ•ดํ”ผ ์ผ€์ด์Šค์— ๋Œ€ํ•œ ๊ฒ€์ฆ ์œ„์ฃผ๋กœ ์ž‘์„ฑํ•˜๊ณ , ์˜ˆ์™ธ ์ผ€์ด์Šค์— ๋Œ€ํ•œ ๊ฒ€์ฆ์€ ๋น„์šฉ์ด ๋‚ฎ์€ ํ…Œ์ŠคํŠธ๋กœ ์ž‘์„ฑํ•˜์ž.

 

๐ŸŽ TDD์™€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ

๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ์ž‘์€ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๊ฒ€์ฆํ•œ๋‹ค. ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰์ด ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฒฉ๋ฆฌ๋œ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ• ๋•Œ๋Š” ํ˜‘๋ ฅ ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

ํ†ตํ•ฉ๊ณผ ๊ณ ๋ฆฝ์ด๋ผ๋Š” ํŠน์ง•์„ ํ†ตํ•ด ํ˜‘๋ ฅ ๊ฐ์ฒด๋ฅผ ์‹ค์ œ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•˜๋Š”์ง€, Mock ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋”ฐ๋ผ์„œ ํ…Œ์ŠคํŠธ ๊ตฌํ˜„์ด ๋‹ฌ๋ผ์ง„๋‹ค.

 

๐ŸŽญ Solitary Tests

Mock ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— Test Double๊ณผ, Stub์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•˜๋Š”๋ฐ,

Test Double -  ์‹ค ๊ฐ์ฒด ๋Œ€์‹  ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ์ข…๋ฅ˜์˜ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ผ๋ฐ˜์šฉ์–ด, ์ฆ‰ ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์งœ๋กœ ๋Œ€์ฒด

Stub - Test Double์˜ ๋™์ž‘์„ ์‚ฌ์ „์— ์ •์˜ํ•˜๋Š” ํ–‰์œ„

 

์ผ๋ฐ˜์ ์œผ๋กœ 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด Mock ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ Subbing ํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. Mockito ํ™œ์šฉ
  2. MockitoExtension ํ™œ์šฉ
  3. Spring์„ ํ™œ์šฉํ•œ Stubbing

 

๐Ÿ”Ž ํ†ตํ•ฉ vs ๊ณ ๋ฆฝ

ํ˜‘๋ ฅ ๊ฐ์ฒด๋ฅผ ์‹ค์ œ ๊ฐ์ฒด๋กœ ํ•ด์•ผํ• ๊นŒ? ๊ฐ€์งœ ๊ฐ์ฒด๋กœ ํ•ด์•ผํ• ๊นŒ?

์‹ค์ œ ๊ฐ์ฒด๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํ˜‘๋ ฅ ๊ฐ์ฒด์˜ ํ–‰์œ„๋ฅผ ํ˜‘๋ ฅ ๊ฐ์ฒด ์Šค์Šค๋กœ ์ •์˜ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ˜‘๋ ฅ ๊ฐ์ฒด์˜ ์ƒ์„ธ ๊ตฌํ˜„์— ๋Œ€ํ•ด ์•Œ ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ, ํ˜‘๋ ฅ ๊ฐ์ฒด์˜ ์ •์ƒ ๋™์ž‘ ์—ฌ๋ถ€์— ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค.

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

๋‚ด ์ƒ๊ฐ์œผ๋กœ, ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์‹ค ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์‚ด์•„์žˆ๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋งŒ์•ฝ, ๋™์ž‘์„ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค์ธ๋ฐ mock ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„๋•Œ๋„ ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ํ•œ๋‹ค๋ฉด ์‹คํŒจํ•ด์•ผ ํ•  ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋Š” ์ผ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ, ๋žœ๋คํ•œ ๊ฐ’์„ ์ถœ๋ ฅํ•˜๋Š” ํด๋ž˜์Šค๊ฑฐ๋‚˜ ์™ธ๋ถ€์™€ ํ†ต์‹ ์„ ํ†ตํ•ด ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด mock์„ ํ™œ์šฉํ•˜๋Š”๊ฒŒ ๋งž๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. 

 

  • ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ ๊ณต์œ 
  • ๋„ค์ด๋ฒ„ ๋ฐด๋“œ ๊ณต์œ 
  • ํŽ˜์ด์Šค๋ถ ๊ณต์œ 
  • ์นด์นด์˜ค์Šคํ† ๋ฆฌ ๊ณต์œ