๐Ÿช kakaotech campus

์นดํ…Œ์ผ | [STEP2 clone coding] 3์ฃผ์ฐจ ๊ณผ์ œ

c0zi 2023. 7. 14. 23:40

3์ฃผ์ฐจ

์นด์นด์˜ค ํ…Œํฌ ์บ ํผ์Šค 2๋‹จ๊ณ„ - BE - 3์ฃผ์ฐจ ํด๋ก  ๊ณผ์ œ

๊ณผ์ œ๋ช…

1. ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋‹จ์œ„ํ…Œ์ŠคํŠธ
 

๊ณผ์ œ ์„ค๋ช…

1. ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋‹จ์œ„ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ œ์ถœํ•˜์‹œ์˜ค.
2. ์ฟผ๋ฆฌ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ฉด์„œ ๊ฐ€์žฅ ์ข‹์€ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์‹œ์˜ค.

 

๊ณผ์ œ ์ƒ์„ธ : ์ˆ˜๊ฐ•์ƒ๋“ค์ด ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์œ ๋…ํ•ด์•ผํ•  ๊ฒƒ

์•„๋ž˜ ํ•ญ๋ชฉ์€ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•˜์—ฌ ๊ณผ์ œ ์ˆ˜ํ–‰ํ•ด์ฃผ์„ธ์š”!

 

๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋‹จ์œ„ํ…Œ์ŠคํŠธ๊ฐ€ ๊ตฌํ˜„๋˜์—ˆ๋Š”๊ฐ€?
ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ๋ผ๋ฆฌ ์œ ๊ธฐ์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜๋Š”๊ฐ€? (ํ…Œ์ŠคํŠธ๋Š” ๊ฒฉ๋ฆฌ์„ฑ์ด ํ•„์š”ํ•˜๋‹ค)
Persistene Context๋ฅผ clearํ•˜์—ฌ์„œ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ตฌํ˜„๋˜์—ˆ๋Š”๊ฐ€? (๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ JPA๋ฅผ ์ด์šฉํ•ด์„œ insert ํ•  ์˜ˆ์ •์ธ๋ฐ, ๋ ˆํฌ์ง€ํ† ๋ฆฌ ํ…Œ์ŠคํŠธ์‹œ์— ์˜์†ํ™”๋œ ๋ฐ์ดํ„ฐ ๋•Œ๋ฌธ์— ์ฟผ๋ฆฌ๋ฅผ ์ œ๋Œ€๋กœ ๋ณด์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—)
ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์ฟผ๋ฆฌ ๊ด€๋ จ๋œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ select๋ฅผ ์œ ๋ฐœํ•˜์ง€ ์•Š๋Š”์ง€? (์ ์ ˆํ•œ ํ•œ๋ฐฉ์ฟผ๋ฆฌ, ํšจ์œจ์ ์ธ in query, N+1 ๋ฌธ์ œ ๋“ฑ์ด ํ•ด๊ฒฐ๋œ ์ฟผ๋ฆฌ)
BDD ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„๋˜์—ˆ๋Š”๊ฐ€? given, when, then

 


1. ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋‹จ์œ„ํ…Œ์ŠคํŠธ


01) ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋‹จ์œ„ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์—…๋กœ๋“œํ•˜์‹œ์˜ค.

 


๐Ÿ“ ์‚ฌ์ „ ๊ฐœ๋…

 

โ…ฐ. ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•๋ก 

 

TDD(ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ)์˜ ๊ฐœ๋ฐœ ์ ‘๊ทผ ๋ฐฉ์‹
- Outside In
- Inside Out

 

1. Outside In

 

  • ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ์˜ ์ผ๋ฐ˜์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹
  • ์™ธ๋ถ€ ๋™์ž‘์ด๋‚˜ ์‹œ์Šคํ…œ์˜ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI)๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋‚ด๋ถ€ ๊ตฌํ˜„์œผ๋กœ ์ง„ํ–‰
  • ์‚ฌ์šฉ์ž์˜ ์š”๊ตฌ์‚ฌํ•ญ์ด๋‚˜ ๊ธฐ๋Šฅ์„ ๋จผ์ € ์ •์˜ํ•˜๊ณ  ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑ
  • ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ ํ›„์—๋Š” ํ•ด๋‹น ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ
  • ์™ธ๋ถ€์—์„œ ๋‚ด๋ถ€๋กœ ์ง„ํ–‰ํ•˜๋ฉด์„œ ํ•„์š”ํ•œ ๊ฐ์ฒด ๋˜๋Š” ๋ชจ๋“ˆ๋“ค์„ ์Šคํ… ๋˜๋Š” ๋ชฉ(mock)์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰
  • ์™ธ๋ถ€์™€ ๋‚ด๋ถ€ ๊ฐ„์˜ ํ˜‘๋ ฅ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ์— ์œ ์šฉํ•œ ๋ฐฉ์‹

 

2. Inside Out

 

  • ๋‚ด๋ถ€ ๊ตฌํ˜„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์™ธ๋ถ€ ๋™์ž‘์ด๋‚˜ UI๋กœ ์ง„ํ–‰
  • ์‹œ์Šคํ…œ์˜ ๋‚ด๋ถ€์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์™ธ๋ถ€๋กœ ํ–ฅํ•ด๊ฐ€๋Š” ๋ฐฉ์‹
  • ์‹œ์Šคํ…œ์˜ ๋‚ด๋ถ€ ๋กœ์ง์ด๋‚˜ ๊ตฌํ˜„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑ
  • ๋‚ด๋ถ€ ๊ตฌํ˜„์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ  ํ•ด๋‹น ๊ตฌํ˜„์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑ
  • ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•˜๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•œ ํ›„์—๋Š” ์™ธ๋ถ€ ๋™์ž‘์ด๋‚˜ UI๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๋‹จ๊ณ„๋กœ ์ง„ํ–‰
  • ๋‚ด๋ถ€ ๋กœ์ง์˜ ์ •ํ™•์„ฑ์— ๋” ์ค‘์ ์„ ๋‘ 

 

Outside In๊ณผ Inside Out์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹œ์Šคํ…œ์„ ๊ฐœ๋ฐœํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•œ ๊ด€์ ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. ๊ฐ ๋ฐฉ์‹์€ ์ƒํ™ฉ๊ณผ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์ ํ•ฉํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฉฐ, ํ”„๋กœ์ ํŠธ์˜ ํŠน์„ฑ์— ๋”ฐ๋ผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 


โ…ฑ. ์—ฐ๊ด€๊ด€๊ณ„

 

Hibernate๋Š” ๊ฐ์ฒด-๊ด€๊ณ„ ๋งคํ•‘(Object-Relational Mapping, ORM)์„ ์ง€์›ํ•˜์—ฌ, ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜ ๋ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์™€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ” ๊ฐ„์˜ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค. Hibernate์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ์ง€์›ํ•œ๋‹ค.

 

1. ์ผ๋Œ€์ผ(One-to-One) : ์—ฐ๊ด€๊ด€๊ณ„ ๋‘ ๊ฐœ์˜ ์—”ํ‹ฐํ‹ฐ ๊ฐ„์— ํ•˜๋‚˜์˜ ๊ด€๊ณ„๋งŒ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ

2. ์ผ๋Œ€๋‹ค(One-to-Many) : ์—ฐ๊ด€๊ด€๊ณ„ ํ•˜๋‚˜์˜ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ ์—ฌ๋Ÿฌ ๊ฐœ์™€ ์—ฐ๊ด€๋œ ๊ฒฝ์šฐ

3. ๋‹ค๋Œ€์ผ(Many-to-One) : ์—ฐ๊ด€๊ด€๊ณ„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ํ•˜๋‚˜์˜ ์—”ํ‹ฐํ‹ฐ์™€ ์—ฐ๊ด€๋œ ๊ฒฝ์šฐ

4. ๋‹ค๋Œ€๋‹ค(Many-to-Many) : ์—ฐ๊ด€๊ด€๊ณ„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์—”ํ‹ฐํ‹ฐ์™€ ์—ฐ๊ด€๋œ ๊ฒฝ์šฐ

 

์—ฐ๊ด€๊ด€๊ณ„๋ฅผ ๋งคํ•‘ํ•  ๋•Œ๋Š” @ManyToOne, @OneToMany, @OneToOne, @ManyToMany ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งคํ•‘ํ•œ๋‹ค. ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์€ mappedBy ์†์„ฑ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. Hibernate์—์„œ๋Š” ์—ฐ๊ด€๊ด€๊ณ„์˜ ์„ค์ •์„ ํ†ตํ•ด ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๋งคํ•‘ํ•˜๊ณ , ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ SQL ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ƒํ˜ธ์ž‘์šฉํ•œ๋‹ค. User, Board, Reply ํ…Œ์ด๋ธ”์„ ์„ค๊ณ„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์„ค์ •๋œ๋‹ค.

 

FK๋Š” N์ชฝ์— ๋ถ™์ด๋ฉด ๋˜๋ฉฐ, N ์ชฝ์ด ํ•ญ์ƒ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์ด๋‹ค.

 

User(1) - Board(N)
User(1) - Reply(N)
Board(1) - Reply(N)

 


โ…ฒ. DataJpaTest

 

1. ์ž„๋ฒ ๋””๋“œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: @DataJpaTest ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ž„๋ฒ ๋””๋“œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆฐ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์‚ฌ์šฉ๋˜๋ฉฐ, ๊ฐ๊ฐ์˜ ํ…Œ์ŠคํŠธ๋งˆ๋‹ค ๋…๋ฆฝ์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

 

2. JPA ์„ค์ •: @DataJpaTest ๋Š” JPA์™€ ๊ด€๋ จ๋œ ์„ค์ •์„ ์ž๋™์œผ๋กœ ๊ตฌ์„ฑํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด JPA ์—”ํ‹ฐํ‹ฐ์™€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

3. ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ JPA ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์Šค์บ”: @DataJpaTest๋Š” ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ JPA ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•œ๋‹ค. ๋”ฐ๋ผ์„œ JPA ์—”ํ‹ฐํ‹ฐ์™€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

4. ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ: @DataJpaTest ๋Š” ๊ฐ๊ฐ์˜ ํ…Œ์ŠคํŠธ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ํŠธ๋žœ์žญ์…˜์„ ์ž๋™์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ , ํ…Œ์ŠคํŠธ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๋กค๋ฐฑํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ƒํƒœ๋ฅผ ๊ฒฉ๋ฆฌ์‹œ์ผœ ๊ฐ๊ฐ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค.

 

5. ๊ธฐํƒ€ ์ง€์› ๊ธฐ๋Šฅ: @DataJpaTest ๋Š” JPA ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์œ„ํ•ด ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, TestEntityManager ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ…Œ์ŠคํŠธ์šฉ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์‰ฝ๊ฒŒ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•  ์ˆ˜ ์žˆํ•œ๋‹ค.

 


โ…ณ. BDD ํŒจํ„ด

 

Given-When-Then

  • ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํŒจํ„ด์œผ๋กœ, ํ…Œ์ŠคํŠธ์˜ ์ƒํ™ฉ, ๋™์ž‘, ๊ฒฐ๊ณผ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜๊ณ  ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ํ…Œ์ŠคํŠธ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์ดํ•ด๋„๋ฅผ ๋†’์ด๋ฉฐ, ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ๋„์›€

 

1. Given (์ฃผ์–ด์ง„ ์ƒํ™ฉ): ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•œ๋‹ค. ํ…Œ์ŠคํŠธ์— ํ•„์š”ํ•œ ๊ฐ์ฒด, ๋ฐ์ดํ„ฐ ๋˜๋Š” ํ™˜๊ฒฝ์„ ์ค€๋น„ํ•œ๋‹ค.

 

2. When (๋™์ž‘): ์‹ค์ œ๋กœ ํ…Œ์ŠคํŠธํ•˜๋ ค๋Š” ๋™์ž‘์ด ๋ฐœ์ƒํ•œ๋‹ค. ํŠน์ • ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋“ฑ์˜ ๋™์ž‘์„ ์‹คํ–‰ํ•œ๋‹ค.

 

3. Then (๊ฒฐ๊ณผ): ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ช…์‹œํ•œ๋‹ค. ์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘์˜ ์ถœ๋ ฅ, ์ƒํƒœ ๋ณ€ํ™” ๋˜๋Š” ์˜ˆ์™ธ ๋ฐœ์ƒ ๋“ฑ์„ ํ™•์ธํ•œ๋‹ค. ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋‹จ์–ธ๋ฌธ(assertion)์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๊ฒฐ๊ณผ์™€ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋น„๊ตํ•œ๋‹ค.

 


 

JPA Repository๋ฅผ ์ž˜ ๋ชฐ๋ผ์„œ ์ด๋ฒˆ ๊ณผ์ œ ์ง„์งœ ๋งŽ์ด ๋ง‰๋ง‰ํ–ˆ๋‹ค....

๊ทธ๋ž˜์„œ JPA Repository๋ถ€ํ„ฐ ๊ณต๋ถ€ํ•จ

 

1. CartJPARepositoryTest

 
@Import(ObjectMapper.class)
@DataJpaTest
public class CartJPARepositoryTest extends DummyEntity {

    @Autowired
    private EntityManager em;

    @Autowired
    private ProductJPARepository productJPARepository;

    @Autowired
    private OptionJPARepository optionJPARepository;

    @Autowired
    private CartJPARepository cartJPARepository;

    @Autowired
    private UserJPARepository userJPARepository;

    @Autowired
    private ObjectMapper om;

    @BeforeEach
    public void setUp(){

        // ๋”๋ฏธ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

        // user ์ €์žฅ
        User user = userJPARepository.save(newUser("jihye"));

        // product, option Dummy ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ถˆ๋Ÿฌ์˜ด
        List<Product> productListPS = productJPARepository.saveAll(productDummyList());
        List<Option> optionListPS = optionJPARepository.saveAll(optionDummyList(productListPS));

        // newCart(User user, Option option, Integer quantity)
        cartJPARepository.save(newCart(user, optionListPS.get(0),1));
        cartJPARepository.save(newCart(user, optionListPS.get(1),1));

        em.clear();
    }
}

 

@Autowired : ์Šคํ”„๋ง DI(Dependency Injection)์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

์Šคํ”„๋ง์—์„œ ๋นˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ ์ดํ›„ @Autowired๋ฅผ ์„ค์ •ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋˜๊ณ , ์ธ์Šคํ„ด์Šค๊ฐ€ ์ž๋™์œผ๋กœ ์ฃผ์ž…๋œ๋‹ค. ์ฆ‰, ํ•ด๋‹น ๋ณ€์ˆ˜ ๋ฐ ๋ฉ”์„œ๋“œ์— ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๋Š” Bean์„ ์ž๋™์œผ๋กœ ๋งคํ•‘ํ•ด์ฃผ๋Š” ๊ฐœ๋…์ด๋‹ค. @Autowired ๋Š” ๋ณ€์ˆ˜, Setter๋ฉ”์„œ๋“œ, ์ƒ์„ฑ์ž, ์ผ๋ฐ˜ ๋ฉ”์„œ๋“œ์— ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

EntityManager๋Š” JPA Repository์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ์—”ํ‹ฐํ‹ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

๋จผ์ €, setUp() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค. ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ์™€ ์˜ต์…˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  cartJPARepository์— save() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด user์™€ ์˜ต์…˜, ์ˆ˜๋Ÿ‰์„ ์ €์žฅํ•œ๋‹ค.

 

Cart Find Test

@DisplayName("์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ ํ…Œ์ŠคํŠธ")
@Test
public void cart_findAll_test() {

    //given
    int id = 1;

    //when
    List<Cart> cartListPS = cartJPARepository.findByUserId(id);

    //then
    Assertions.assertThat(cartListPS.get(0).getQuantity()).isEqualTo(1);
    Assertions.assertThat(cartListPS.get(0).getPrice()).isEqualTo(10000);
    Assertions.assertThat(cartListPS.get(0).getOption().getOptionName()).isEqualTo("01. ์Šฌ๋ผ์ด๋”ฉ ์ง€ํผ๋ฐฑ ํฌ๋ฆฌ์Šค๋งˆ์Šค์—๋””์…˜ 4์ข…");
    Assertions.assertThat(cartListPS.get(0).getUser().getUsername()).isEqualTo("jihye");

}

 

cart_findAll_test๋Š” ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ ์กฐํšŒํ•˜๋Š” ํ…Œ์ŠคํŠธ์ด๋‹ค. 

id๋ฅผ 1๋กœ ์ฃผ๊ณ  cartList ๋‚ด์—์„œ ํ•ด๋‹น ์•„์ด๋””๋ฅผ ๊ฐ–๋Š” cart๋ฅผ ์ฐพ๋Š”๋‹ค.

 

๊ทธ๋Ÿฐ ๋’ค์— ์ˆ˜๋Ÿ‰๊ณผ ๊ฐ€๊ฒฉ, ์˜ต์…˜, ์œ ์ € ์ด๋ฆ„ ๋“ฑ์„ ํ™•์ธํ•œ๋‹ค.

 

Cart Save Test

@DisplayName("์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ ํ…Œ์ŠคํŠธ")
@Test
public void cart_save_test() {

    //given
    User user = userJPARepository.findById(1).get();
    Option option = optionJPARepository.findById(5).get();
    newCart(user, option, 1);

    //when
    Cart cart = cartJPARepository.save(newCart(user, option, 1));
    System.out.println("id : " + cart.getId());

    //then

}

 

๋‹ค์Œ์œผ๋กœ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ๋ฅผ ํ…Œ์ŠคํŠธ ํ•œ๋‹ค. newCart() ๋ฉ”์„œ๋“œ๋กœ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋„ฃ๋Š”๋‹ค.

 

Cart Update Test

@DisplayName("์žฅ๋ฐ”๊ตฌ๋‹ˆ ์—…๋ฐ์ดํŠธ ํ…Œ์ŠคํŠธ")
@Test
public void cart_update_test(){

    //given
    int id = 1;
    int quantity = 3;
    int price;
    Cart selectCart = cartJPARepository.findById(id).get();

    //when
    price = selectCart.getOption().getPrice() * quantity;
    selectCart.update(quantity, price);
    em.flush();

    //then

}

 

selectCart๋ฅผ ํ†ตํ•ด ์„ ํƒํ•œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

 

์—…๋ฐ์ดํŠธ ํ›„์˜ price๋Š” ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‚ด์˜ ์˜ต์…˜์˜ ๊ฐ€๊ฒฉ๊ณผ ์ˆ˜๋Ÿ‰์„ ๊ณฑํ•˜์—ฌ ๊ณ„์‚ฐ ํ•œ๋‹ค.

 

Cart Delete Test

@DisplayName("์žฅ๋ฐ”๊ตฌ๋‹ˆ ์‚ญ์ œ ํ…Œ์ŠคํŠธ")
@Test
public void cart_deleteByUserId_test(){

    //given
    int id = 1;

    //when
    cartJPARepository.deleteByUserId(id);
    List<Cart> cartListPS = cartJPARepository.findByUserId(id);

    //given
    Assertions.assertThat(cartListPS.size()).isEqualTo(0);
}

 

2. OrderJPARepositoryTest

 

@Import(ObjectMapper.class)
@DataJpaTest
public class OrderJPARepositoryTest extends DummyEntity {
    

    @Autowired
    private EntityManager em;

    @Autowired
    private OrderJPARepository orderJPARepository;

    @Autowired
    private ItemJPARepository itemJPARepository;

    @Autowired
    private UserJPARepository userJPARepository;

    @Autowired
    private ProductJPARepository productJPARepository;

    @Autowired
    private OptionJPARepository optionJPARepository;

    @Autowired
    private CartJPARepository cartJPARepository;

    @BeforeEach
    public void setUp(){

        User userPS = userJPARepository.save(newUser("jihye"));

        List<Product> productListPS = productJPARepository.saveAll(productDummyList());
        List<Option> optionListPS = optionJPARepository.saveAll(optionDummyList(productListPS));
        Order orderPS = orderJPARepository.save(newOrder(userPS));

        Cart cartPS1 = newCart(userPS, optionListPS.get(0), 1);
        Cart cartPS2 = newCart(userPS, optionListPS.get(1), 1);

        itemJPARepository.save(newItem(cartPS1, orderPS));
        itemJPARepository.save(newItem(cartPS2, orderPS));

        em.clear();
    }

    @DisplayName("์ฃผ๋ฌธ ํ…Œ์ŠคํŠธ")
    @Test
    public void item_findByOrderId_test(){

        //given
        int id = 1;

        //when
        List<Item> itemListPS = itemJPARepository.findByOrderId(id);

        //then
        Assertions.assertThat(itemListPS.get(0).getId()).isEqualTo(1);
        Assertions.assertThat(itemListPS.get(0).getPrice()).isEqualTo(10000);
        Assertions.assertThat(itemListPS.get(0).getQuantity()).isEqualTo(1);
        Assertions.assertThat(itemListPS.get(0).getOrder().getId()).isEqualTo(1);

    }
}

 

itemJPARepository ์— ์ƒˆ๋กœ์šด ์ฃผ๋ฌธ ์•„์ดํ…œ๋“ค์„ ๋„ฃ์–ด๋‘๊ณ  ์ฃผ๋ฌธ ๋‚ด์—ญ์ด ๋ฐ์ดํ„ฐ์™€ ๋งž๋Š”์ง€ ๋น„๊ตํ•œ๋‹ค.