๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ฅผ ์ฌ์ฉํ ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ ํ ์คํ ์ฌ์ธต ๋ถ์. ๊ฒฌ๊ณ ํ๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํ ๋ชจ๋ฒ ์ฌ๋ก, ๋๊ตฌ ๋ฐ ๊ธฐ์ ์ ๋ฐฐ์๋ณด์ธ์.
ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ ํ ์คํ : ๊ฒฌ๊ณ ํ UI๋ฅผ ์ํ ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ ๋ง์คํฐํ๊ธฐ
๋์์์ด ์งํํ๋ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ ๊ฒฌ๊ณ ํ๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์ฌ์ฉ์ ์ธํฐํ์ด์ค(UI)๋ฅผ ๋ง๋๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ ํ ์คํ , ํนํ ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ์ด ๋ชฉํ๋ฅผ ๋ฌ์ฑํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋๋ ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ๋ฅผ ์ํ ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ์ ๊ด๋ จ๋ ๊ฐ๋ , ์ด์ , ๊ธฐ์ ๋ฐ ๋๊ตฌ๋ฅผ ํ๊ตฌํ์ฌ ๊ณ ํ์ง์ ์ ๋ขฐํ ์ ์๋ UI๋ฅผ ๊ตฌ์ถํ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ๋ฌด์์ธ๊ฐ?
์ผ๋ฐ์ ์ผ๋ก ๋จ์ ํ ์คํธ๋ ์์คํ ์ ๋ค๋ฅธ ๋ถ๋ถ๊ณผ ๊ฒฉ๋ฆฌํ์ฌ ๊ฐ๋ณ ์ฝ๋ ๋จ์๋ฅผ ํ ์คํธํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ ํ ์คํธ์ ๋งฅ๋ฝ์์ ์ด๋ ๋ฒํผ, ํผ ์ ๋ ฅ ๋๋ ๋ชจ๋ฌ๊ณผ ๊ฐ์ ๋จ์ผ ์ปดํฌ๋ํธ๋ฅผ ์ข ์์ฑ๊ณผ ์ฃผ๋ณ ์ปจํ ์คํธ์ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ์ธ๋ถ ์ข ์์ฑ์ ๋ช ์์ ์ผ๋ก ๋ชจ์(mock)ํ๊ฑฐ๋ ์คํ (stub) ์ฒ๋ฆฌํ์ฌ ์ปดํฌ๋ํธ์ ๋์์ด ์์ํ๊ฒ ๊ทธ ์์ฒด์ ์ฅ์ ์ ๋ฐ๋ผ ํ๊ฐ๋๋๋ก ํ ๋จ๊ณ ๋ ๋์๊ฐ๋๋ค.
ํ๋์ ๋ ๊ณ ๋ธ๋ก์ ํ ์คํธํ๋ ๊ฒ๊ณผ ๊ฐ๋ค๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. ๋ค๋ฅธ ๋ธ๋ก๊ณผ ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋์ด ์๋์ง์ ๊ด๊ณ์์ด ํด๋น ๋ธ๋ก์ด ์์ฒด์ ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ณ ์ถ์ ๊ฒ์ ๋๋ค. ๊ฒฐํจ์ด ์๋ ๋ธ๋ก์ด ๋ ๊ณ ์ฐฝ์๋ฌผ์ ๋ค๋ฅธ ๊ณณ์์ ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ ๊ฒ์ ์ํ์ง ์์ ๊ฒ์ ๋๋ค.
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ์ ์ฃผ์ ํน์ง:
- ๋จ์ผ ์ปดํฌ๋ํธ์ ์ง์ค: ๊ฐ ํ ์คํธ๋ ํ๋์ ํน์ ์ปดํฌ๋ํธ๋ฅผ ๋์์ผ๋ก ํด์ผ ํฉ๋๋ค.
- ์ข ์์ฑ์ผ๋ก๋ถํฐ์ ๊ฒฉ๋ฆฌ: ์ธ๋ถ ์ข ์์ฑ(์: API ํธ์ถ, ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ๋ค๋ฅธ ์ปดํฌ๋ํธ)์ ๋ชจ์(mock)๋๊ฑฐ๋ ์คํ (stub) ์ฒ๋ฆฌ๋ฉ๋๋ค.
- ๋น ๋ฅธ ์คํ ์๋: ๊ฒฉ๋ฆฌ๋ ํ ์คํธ๋ ์ ์ํ๊ฒ ์คํ๋์ด์ผ ํ๋ฉฐ, ๊ฐ๋ฐ ์ค ๋น๋ฒํ ํผ๋๋ฐฑ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ๊ฒฐ์ ๋ก ์ ๊ฒฐ๊ณผ: ๋์ผํ ์ ๋ ฅ์ด ์ฃผ์ด์ง๋ฉด ํ ์คํธ๋ ํญ์ ๋์ผํ ์ถ๋ ฅ์ ์์ฑํด์ผ ํฉ๋๋ค. ์ด๋ ์ ์ ํ ๊ฒฉ๋ฆฌ ๋ฐ ๋ชจ์(mocking)๋ฅผ ํตํด ๋ฌ์ฑ๋ฉ๋๋ค.
- ๋ช ํํ ๋จ์ธ(Assertion): ํ ์คํธ๋ ์์๋๋ ๋์์ ๋ช ํํ๊ฒ ์ ์ํ๊ณ ์ปดํฌ๋ํธ๊ฐ ์์๋๋ก ๋์ํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
์ ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ๋ฅผ ์ํด ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ฅผ ๋์ ํด์ผ ํ๋๊ฐ?
ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ์ ๋ํ ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ์ ํฌ์ํ๋ฉด ์๋ง์ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค:
1. ์ฝ๋ ํ์ง ํฅ์ ๋ฐ ๋ฒ๊ทธ ๊ฐ์
๊ฐ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ๊ผผ๊ผผํ๊ฒ ํ ์คํธํจ์ผ๋ก์จ ๊ฐ๋ฐ ์ฃผ๊ธฐ ์ด๊ธฐ์ ๋ฒ๊ทธ๋ฅผ ์๋ณํ๊ณ ์์ ํ ์ ์์ต๋๋ค. ์ด๋ ์ฝ๋๋ฒ ์ด์ค๊ฐ ๋ฐ์ ํจ์ ๋ฐ๋ผ ๋ ๋์ ์ฝ๋ ํ์ง๋ก ์ด์ด์ง๊ณ ํ๊ท(regression) ๋ฐ์ ๊ฐ๋ฅ์ฑ์ ์ค์ ๋๋ค. ๋ฒ๊ทธ๋ฅผ ๋นจ๋ฆฌ ์ฐพ์์๋ก ์์ ๋น์ฉ์ด ์ ๋ ดํด์ ธ ์ฅ๊ธฐ์ ์ผ๋ก ์๊ฐ๊ณผ ์์์ ์ ์ฝํ ์ ์์ต๋๋ค.
2. ์ฝ๋ ์ ์ง๋ณด์์ฑ ๋ฐ ๋ฆฌํฉํ ๋ง ๊ฐ์
์ ์์ฑ๋ ๋จ์ ํ ์คํธ๋ ์ด์์๋ ๋ฌธ์ ์ญํ ์ ํ์ฌ ๊ฐ ์ปดํฌ๋ํธ์ ์์ ๋์์ ๋ช ํํ ํฉ๋๋ค. ์ปดํฌ๋ํธ๋ฅผ ๋ฆฌํฉํ ๋งํ๊ฑฐ๋ ์์ ํด์ผ ํ ๋, ๋จ์ ํ ์คํธ๋ ์์ ๋ง์ ์ ๊ณตํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์น ์๊ฒ ๊ธฐ์กด ๊ธฐ๋ฅ์ ์์์ํค์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๋ณต์ก์ฑ์ ์ดํดํ๊ธฐ ์ด๋ ค์ธ ์ ์๋ ํฌ๊ณ ๋ณต์กํ ํ๋ก์ ํธ์์ ํนํ ์ ์ฉํฉ๋๋ค. ์ ์ธ๊ณ์ ์ธ ์ ์์๊ฑฐ๋ ํ๋ซํผ์์ ์ฌ์ฉ๋๋ ๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ๋ฆฌํฉํ ๋งํ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ํฌ๊ด์ ์ธ ๋จ์ ํ ์คํธ๋ ๋ฆฌํฉํ ๋ง์ด ๊ฒฐ์ ๋๋ ๊ณ์ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๊ธฐ์กด ์ฌ์ฉ์ ์ํฌํ๋ก์ฐ๋ฅผ ์์์ํค์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
3. ๋ ๋น ๋ฅธ ๊ฐ๋ฐ ์ฃผ๊ธฐ
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ์ผ๋ฐ์ ์ผ๋ก ํตํฉ ํ ์คํธ๋ ์๋ํฌ์๋(end-to-end) ํ ์คํธ๋ณด๋ค ์คํ ์๋๊ฐ ํจ์ฌ ๋น ๋ฆ ๋๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ์ ์ํ ํผ๋๋ฐฑ์ ๋ฐ์ ๊ฐ๋ฐ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ํํ ์ ์์ต๋๋ค. ๋ ๋น ๋ฅธ ํผ๋๋ฐฑ ๋ฃจํ๋ ์์ฐ์ฑ ํฅ์๊ณผ ์์ฅ ์ถ์ ์๊ฐ ๋จ์ถ์ผ๋ก ์ด์ด์ง๋๋ค.
4. ์ฝ๋ ๋ณ๊ฒฝ์ ๋ํ ์์ ๊ฐ ์ฆ๊ฐ
ํฌ๊ด์ ์ธ ๋จ์ ํ ์คํธ ์ค์ํธ๋ฅผ ๊ฐ์ถ๋ฉด ๊ฐ๋ฐ์๋ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋ณ๊ฒฝํ ๋ ๋ ํฐ ์์ ๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค. ํ ์คํธ๊ฐ ๋ชจ๋ ํ๊ท๋ฅผ ์ก์๋ผ ๊ฒ์ด๋ผ๋ ์ฌ์ค์ ์๋ฉด ๊ธฐ์กด ๊ธฐ๋ฅ ์์์ ๋ํ ๋๋ ค์ ์์ด ์๋ก์ด ๊ธฐ๋ฅ๊ณผ ๊ฐ์ ์ฌํญ์ ๊ตฌํํ๋ ๋ฐ ์ง์คํ ์ ์์ต๋๋ค. ์ด๋ ๋น๋ฒํ ๋ฐ๋ณต๊ณผ ๋ฐฐํฌ๊ฐ ์ผ๋ฐ์ ์ธ ์ ์์ผ ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
5. ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ(TDD) ์ด์ง
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ(TDD)์ ์ด์์ ๋๋ค. TDD๋ ์ค์ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ ์ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ ํฌํจํ๋ฉฐ, ์ด๋ ์ปดํฌ๋ํธ์ ์๊ตฌ ์ฌํญ๊ณผ ์ค๊ณ๋ฅผ ๋ฏธ๋ฆฌ ์๊ฐํ๊ฒ ๋ง๋ญ๋๋ค. ์ด๋ ๋ ์ง์ค๋๊ณ ํ ์คํธ ๊ฐ๋ฅํ ์ฝ๋๋ก ์ด์ด์ง๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์ ์์น์ ๋ฐ๋ผ ํตํ๋ฅผ ํ์ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฐํ ๋ TDD๋ฅผ ์ฌ์ฉํ๋ฉด ๋จผ์ ๋ก์ผ์ผ์ ๋ฐ๋ผ ํตํ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ํ๋์๋์ง(์: ํ๋์ค๋ ์ ๋ก, ์ผ๋ณธ์ ์, ๋ฏธ๊ตญ์ ๋ฌ๋ฌ) ํ์ธํ๋ ํ ์คํธ๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ฅผ ์ํ ์ค์ฉ์ ์ธ ๊ธฐ์
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ตฌํํ๋ ค๋ฉด ์ ์ ํ ์ค์ , ๋ชจ์(mocking) ๊ธฐ์ ๋ฐ ๋ช ํํ ๋จ์ธ(assertion)์ ์กฐํฉ์ด ํ์ํฉ๋๋ค. ์ฃผ์ ๊ธฐ์ ์ ๋ํ ๋ถ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
1. ์ฌ๋ฐ๋ฅธ ํ ์คํธ ํ๋ ์์ํฌ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ํ
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ์ํด ์ฌ๋ฌ ํ๋ฅญํ ํ ์คํธ ํ๋ ์์ํฌ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ธ๊ธฐ ์๋ ์ ํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Jest: ์ฌ์ฉ ํธ์์ฑ, ๋ด์ฅ๋ ๋ชจ์(mocking) ๊ธฐ๋ฅ ๋ฐ ๋ฐ์ด๋ ์ฑ๋ฅ์ผ๋ก ๋๋ฆฌ ์ฌ์ฉ๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค. ํนํ ๋ฆฌ์กํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํ์ง๋ง ๋ค๋ฅธ ํ๋ ์์ํฌ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- Mocha: ์์ฒด ๋จ์ธ(assertion) ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ชจ์(mocking) ๋๊ตฌ๋ฅผ ์ ํํ ์ ์๋ ์ ์ฐํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค. ์ข ์ข ๋จ์ธ์ ์ํด Chai์, ๋ชจ์(mocking)๋ฅผ ์ํด Sinon.JS์ ํจ๊ป ์ฌ์ฉ๋ฉ๋๋ค.
- Jasmine: ํ ์คํธ ์์ฑ์ ์ํ ๊นจ๋ํ๊ณ ๊ฐ๋ ์ฑ ์๋ ๊ตฌ๋ฌธ์ ์ ๊ณตํ๋ ํ๋ ์ฃผ๋ ๊ฐ๋ฐ(BDD) ํ๋ ์์ํฌ์ ๋๋ค. ๋ด์ฅ๋ ๋ชจ์(mocking) ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค.
- Cypress: ์ฃผ๋ก ์๋ํฌ์๋(end-to-end) ํ ์คํธ ํ๋ ์์ํฌ๋ก ์๋ ค์ ธ ์์ง๋ง, ์ปดํฌ๋ํธ ํ ์คํธ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ค์ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ์ปดํฌ๋ํธ์ ์ํธ ์์ฉํ ์ ์๋ ๊ฐ๋ ฅํ๊ณ ์ง๊ด์ ์ธ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
ํ๋ ์์ํฌ์ ์ ํ์ ํ๋ก์ ํธ์ ํน์ ์๊ตฌ ์ฌํญ๊ณผ ํ์ ์ ํธ๋์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. Jest๋ ์ฌ์ฉ ํธ์์ฑ๊ณผ ํฌ๊ด์ ์ธ ๊ธฐ๋ฅ ์ธํธ๋ก ์ธํด ๋ง์ ํ๋ก์ ํธ์ ์ข์ ์ถ๋ฐ์ ์ด ๋ฉ๋๋ค.
2. ์ข ์์ฑ ๋ชจ์(Mocking) ๋ฐ ์คํ (Stubbing)
๋ชจ์(Mocking)์ ์คํ (stubbing)์ ๋จ์ ํ ์คํธ ์ค์ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ๊ธฐ ์ํ ํ์ ๊ธฐ์ ์ ๋๋ค. ๋ชจ์(Mocking)๋ ์ค์ ์ข ์์ฑ์ ๋์์ ๋ชจ๋ฐฉํ๋ ์๋ฎฌ๋ ์ด์ ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์ ํฌํจํ๋ฉฐ, ์คํ (stubbing)์ ์ข ์์ฑ์ ๋ฏธ๋ฆฌ ์ ์๋ ๊ฐ์ ๋ฐํํ๋ ๋จ์ํ๋ ๋ฒ์ ์ผ๋ก ๋์ฒดํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
๋ชจ์(mocking) ๋๋ ์คํ (stubbing)์ด ํ์ํ ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- API ํธ์ถ: ํ ์คํธ ์ค ์ค์ ๋คํธ์ํฌ ์์ฒญ์ ํผํ๊ธฐ ์ํด API ํธ์ถ์ ๋ชจ์(mock)ํฉ๋๋ค. ์ด๋ ํ ์คํธ๊ฐ ๋น ๋ฅด๊ณ ์ ๋ขฐํ ์ ์์ผ๋ฉฐ ์ธ๋ถ ์๋น์ค์ ๋ ๋ฆฝ์ ์ด๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: Redux, Vuex): ํ ์คํธ ์ค์ธ ์ปดํฌ๋ํธ์ ์ํ๋ฅผ ์ ์ดํ๊ธฐ ์ํด ์คํ ์ด์ ์ก์ ์ ๋ชจ์(mock)ํฉ๋๋ค.
- ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ์ปดํฌ๋ํธ์ ๋์์ ๊ฒฉ๋ฆฌํ๊ธฐ ์ํด ์ปดํฌ๋ํธ๊ฐ ์์กดํ๋ ๋ชจ๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชจ์(mock)ํฉ๋๋ค.
- ๋ค๋ฅธ ์ปดํฌ๋ํธ: ๋๋ก๋ ํ ์คํธ ์ค์ธ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ๋์์๋ง ์ง์คํ๊ธฐ ์ํด ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ชจ์(mock)ํ ํ์๊ฐ ์์ต๋๋ค.
๋ค์์ Jest๋ฅผ ์ฌ์ฉํ์ฌ ์ข ์์ฑ์ ๋ชจ์(mock)ํ๋ ๋ช ๊ฐ์ง ์์ ๋๋ค:
// ๋ชจ๋ ๋ชจ์(mocking)
jest.mock('./api');
// ๋ชจ๋ ๋ด ํจ์ ๋ชจ์(mocking)
api.fetchData = jest.fn().mockResolvedValue({ data: 'mocked data' });
3. ๋ช ํํ๊ณ ์๋ฏธ ์๋ ๋จ์ธ(Assertion) ์์ฑ
๋จ์ธ(Assertion)์ ๋จ์ ํ ์คํธ์ ํต์ฌ์ ๋๋ค. ์ด๋ ์ปดํฌ๋ํธ์ ์์ ๋์์ ์ ์ํ๊ณ ๊ทธ๊ฒ์ด ์์๋๋ก ๋์ํ๋์ง ํ์ธํฉ๋๋ค. ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ๋ฉฐ ์ดํดํ๊ธฐ ์ฌ์ด ๋จ์ธ์ ์์ฑํ์ธ์.
๋ค์์ ์ผ๋ฐ์ ์ธ ๋จ์ธ์ ๋ช ๊ฐ์ง ์์ ๋๋ค:
- ์์ ์กด์ฌ ์ฌ๋ถ ํ์ธ:
expect(screen.getByText('Hello World')).toBeInTheDocument();
- ์
๋ ฅ ํ๋ ๊ฐ ํ์ธ:
expect(inputElement.value).toBe('initial value');
- ํจ์ ํธ์ถ ์ฌ๋ถ ํ์ธ:
expect(mockFunction).toHaveBeenCalled();
- ํน์ ์ธ์๋ก ํจ์๊ฐ ํธ์ถ๋์๋์ง ํ์ธ:
expect(mockFunction).toHaveBeenCalledWith('argument1', 'argument2');
- ์์์ CSS ํด๋์ค ํ์ธ:
expect(element).toHaveClass('active');
๋จ์ธ์ ์์ ์ ์ธ ์ธ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌด์์ ํ ์คํธํ๋์ง ๋ช ํํ ํ์ธ์. ์๋ฅผ ๋ค์ด, ํจ์๊ฐ ํธ์ถ๋์๋ค๊ณ ๋ง ๋จ์ธํ๋ ๋์ , ์ฌ๋ฐ๋ฅธ ์ธ์๋ก ํธ์ถ๋์๋ค๊ณ ๋จ์ธํ์ธ์.
4. ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ Storybook ํ์ฉ
์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: Material UI, Ant Design, Bootstrap)๋ ๊ฐ๋ฐ ์๋๋ฅผ ํฌ๊ฒ ๋์ผ ์ ์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ UI ์ปดํฌ๋ํธ๋ฅผ ์ ๊ณตํฉ๋๋ค. Storybook์ ๊ฒฉ๋ฆฌ๋ ํ๊ฒฝ์์ UI ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋ฐํ๊ณ ์ ๋ณด์ด๋ ๋ฐ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋๊ตฌ์ ๋๋ค.
์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋, ๋จ์ ํ ์คํธ๋ ์ปดํฌ๋ํธ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๊ณ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ํน์ ์ปจํ ์คํธ์์ ์์๋๋ก ๋์ํ๋์ง๋ฅผ ํ์ธํ๋ ๋ฐ ์ค์ ์ ๋ฌ์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ ์ง ์ ๋ ฅ์ ์ํด ์ธ๊ณ์ ์ผ๋ก ์ธ์ ๋ฐ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๊ตญ๊ฐ์ ๋ํด ๋ ์ง ํ์์ด ์ฌ๋ฐ๋ฅธ์ง ํ ์คํธํ ์ ์์ต๋๋ค(์: ์๊ตญ์ DD/MM/YYYY, ๋ฏธ๊ตญ์ MM/DD/YYYY).
Storybook์ ํ ์คํธ ํ๋ ์์ํฌ์ ํตํฉํ์ฌ Storybook ์คํ ๋ฆฌ์ ์ปดํฌ๋ํธ์ ์ง์ ์ํธ ์์ฉํ๋ ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ด๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๋ ๋๋ง๋๊ณ ์์๋๋ก ๋์ํ๋์ง ์๊ฐ์ ์ผ๋ก ํ์ธํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
5. ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ(TDD) ์ํฌํ๋ก์ฐ
์์ ์ธ๊ธํ๋ฏ์ด, TDD๋ ์ฝ๋์ ํ์ง๊ณผ ํ ์คํธ ๊ฐ๋ฅ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์๋ ๊ฐ๋ ฅํ ๊ฐ๋ฐ ๋ฐฉ๋ฒ๋ก ์ ๋๋ค. TDD ์ํฌํ๋ก์ฐ๋ ๋ค์ ๋จ๊ณ๋ฅผ ํฌํจํฉ๋๋ค:
- ์คํจํ๋ ํ ์คํธ ์์ฑ: ๋ง๋ค๋ ค๋ ์ปดํฌ๋ํธ์ ์์ ๋์์ ์ ์ํ๋ ํ ์คํธ๋ฅผ ์์ฑํฉ๋๋ค. ์ด ํ ์คํธ๋ ์ปดํฌ๋ํธ๊ฐ ์์ง ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ ์ฒ์์๋ ์คํจํด์ผ ํฉ๋๋ค.
- ํ ์คํธ๋ฅผ ํต๊ณผ์ํค๋ ์ต์ํ์ ์ฝ๋ ์์ฑ: ํ ์คํธ๋ฅผ ํต๊ณผ์ํค๊ธฐ ์ํด ๊ฐ์ฅ ๊ฐ๋จํ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค. ์ด ๋จ๊ณ์์๋ ์ฝ๋๋ฅผ ์๋ฒฝํ๊ฒ ๋ง๋๋ ๊ฒ์ ๋ํด ๊ฑฑ์ ํ์ง ๋ง์ธ์.
- ๋ฆฌํฉํ ๋ง: ์ฝ๋์ ๋์์ธ๊ณผ ๊ฐ๋ ์ฑ์ ํฅ์์ํค๊ธฐ ์ํด ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋งํฉ๋๋ค. ๋ฆฌํฉํ ๋ง ํ์๋ ๋ชจ๋ ํ ์คํธ๊ฐ ๊ณ์ ํต๊ณผํ๋์ง ํ์ธํฉ๋๋ค.
- ๋ฐ๋ณต: ์ปดํฌ๋ํธ์ ๊ฐ ์๋ก์ด ๊ธฐ๋ฅ์ด๋ ๋์์ ๋ํด 1-3๋จ๊ณ๋ฅผ ๋ฐ๋ณตํฉ๋๋ค.
TDD๋ ์ปดํฌ๋ํธ์ ์๊ตฌ ์ฌํญ๊ณผ ์ค๊ณ๋ฅผ ๋ฏธ๋ฆฌ ์๊ฐํ๊ฒ ํ์ฌ ๋ ์ง์ค๋๊ณ ํ ์คํธ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐ ๋์์ ์ค๋๋ค. ์ด ์ํฌํ๋ก์ฐ๋ ์ฃ์ง ์ผ์ด์ค๋ฅผ ํฌํจํ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๋ค๋ฃจ๋ ํ ์คํธ ์์ฑ์ ์ฅ๋ คํ๊ณ , ์ฝ๋์ ๋ํ ๋์ ์์ค์ ์ ๋ขฐ๋๋ฅผ ์ ๊ณตํ๋ ํฌ๊ด์ ์ธ ๋จ์ ํ ์คํธ ์ค์ํธ๋ฅผ ๊ฒฐ๊ณผ๋ก ๋ณ๊ธฐ ๋๋ฌธ์ ์ ์ธ๊ณ์ ์ผ๋ก ์ ์ตํฉ๋๋ค.
ํผํด์ผ ํ ์ผ๋ฐ์ ์ธ ํจ์
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ๊ฐ์น ์๋ ๊ดํ์ด์ง๋ง, ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ํจ์ ์ ์ ์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
1. ๊ณผ๋ํ ๋ชจ์(Mocking)
๋๋ฌด ๋ง์ ์ข ์์ฑ์ ๋ชจ์(mocking)ํ๋ฉด ํ ์คํธ๊ฐ ๊นจ์ง๊ธฐ ์ฝ๊ณ ์ ์ง ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง ์ ์์ต๋๋ค. ๊ฑฐ์ ๋ชจ๋ ๊ฒ์ ๋ชจ์(mocking)ํ๊ณ ์๋ค๋ฉด, ์ค์ ์ปดํฌ๋ํธ๊ฐ ์๋ ๋ชจ์(mock) ๊ฐ์ฒด๋ฅผ ํ ์คํธํ๋ ์ ์ ๋๋ค. ๊ฒฉ๋ฆฌ์ ํ์ค์ฑ ์ฌ์ด์ ๊ท ํ์ ์ ์งํ๊ธฐ ์ํด ๋ ธ๋ ฅํ์ธ์. ์คํ๋ก ์ธํด ์ฌ์ฉํด์ผ ํ ๋ชจ๋์ ์ค์๋ก ๋ชจ์(mock)ํ์ฌ ๋๋ฒ๊น ์ ๋ง์ ์ค๋ฅ์ ํผ๋์ ์ผ๊ธฐํ ์ ์์ต๋๋ค. ์ข์ IDE/๋ฆฐํฐ๋ ์ด๋ฅผ ์ก์๋ด์ผ ํ์ง๋ง ๊ฐ๋ฐ์๋ ์ ์ฌ์ ์ธ ๊ฐ๋ฅ์ฑ์ ์ธ์งํ๊ณ ์์ด์ผ ํฉ๋๋ค.
2. ๊ตฌํ ์ธ๋ถ ์ฌํญ ํ ์คํธ
๋ณ๊ฒฝ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ํ ์คํธํ๋ ๊ฒ์ ํผํ์ธ์. ์ปดํฌ๋ํธ์ ๊ณต๊ฐ API์ ์์ ๋์์ ํ ์คํธํ๋ ๋ฐ ์ง์คํ์ธ์. ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ํ ์คํธํ๋ฉด ํ ์คํธ๊ฐ ์ทจ์ฝํด์ง๊ณ , ์ปดํฌ๋ํธ์ ๋์์ด ๋์ผํ๊ฒ ์ ์ง๋๋๋ผ๋ ๊ตฌํ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ํ ์คํธ๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํฉ๋๋ค.
3. ์ฃ์ง ์ผ์ด์ค ๋ฌด์
๋ชจ๋ ๊ฐ๋ฅํ ์ฃ์ง ์ผ์ด์ค์ ์ค๋ฅ ์กฐ๊ฑด์ ํ ์คํธํด์ผ ํฉ๋๋ค. ์ด๋ ์ ์์ ์ธ ์ํฉ์์๋ ๋ช ํํ์ง ์์ ์ ์๋ ๋ฒ๊ทธ๋ฅผ ์๋ณํ๊ณ ์์ ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ฐ๋ ๊ฒฝ์ฐ, ๋น ์ ๋ ฅ, ์ ํจํ์ง ์์ ๋ฌธ์, ๊ทธ๋ฆฌ๊ณ ๋น์ ์์ ์ผ๋ก ๊ธด ๋ฌธ์์ด์ ๋ํด ์ด๋ป๊ฒ ๋์ํ๋์ง ํ ์คํธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
4. ๋๋ฌด ๊ธธ๊ณ ๋ณต์กํ ํ ์คํธ ์์ฑ
ํ ์คํธ๋ฅผ ์งง๊ณ ์ง์ค์ ์ผ๋ก ์ ์งํ์ธ์. ๊ธธ๊ณ ๋ณต์กํ ํ ์คํธ๋ ์ฝ๊ณ , ์ดํดํ๊ณ , ์ ์ง ๊ด๋ฆฌํ๊ธฐ ์ด๋ ต์ต๋๋ค. ํ ์คํธ๊ฐ ๋๋ฌด ๊ธธ๋ฉด ๋ ์๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ํ ์คํธ๋ก ๋๋๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
5. ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง ๋ฌด์
๋จ์ ํ ์คํธ๋ก ์ปค๋ฒ๋๋ ์ฝ๋์ ๋น์จ์ ์ธก์ ํ๊ธฐ ์ํด ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ธ์. ๋์ ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง๊ฐ ์ฝ๋๊ฐ ๋ฒ๊ทธ๊ฐ ์์์ ๋ณด์ฅํ์ง๋ ์์ง๋ง, ํ ์คํธ ๋ ธ๋ ฅ์ ์์ ์ฑ์ ํ๊ฐํ๋ ๋ฐ ์ ์ฉํ ์งํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋์ ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ชฉํ๋ก ํ๋, ์์ ์ํด ์ง์ ํฌ์ํ์ง ๋ง์ธ์. ํ ์คํธ๋ ๋จ์ํ ์ปค๋ฒ๋ฆฌ์ง ์์น๋ฅผ ๋์ด๊ธฐ ์ํด ์์ฑ๋๋ ๊ฒ์ด ์๋๋ผ ์๋ฏธ ์๊ณ ํจ๊ณผ์ ์ด์ด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, SonarQube๋ ์ข์ ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ ์งํ๊ธฐ ์ํด ํ์ฌ์์ ํํ ์ฌ์ฉ๋ฉ๋๋ค.
์ฃผ์ ๋๊ตฌ๋ค
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ๊ณ ์คํํ๋ ๋ฐ ๋์์ด ๋๋ ์ฌ๋ฌ ๋๊ตฌ๊ฐ ์์ต๋๋ค:
- Jest: ์์ ์ธ๊ธํ๋ฏ์ด, ๋ด์ฅ๋ ๋ชจ์(mocking) ๊ธฐ๋ฅ์ ๊ฐ์ถ ํฌ๊ด์ ์ธ ์๋ฐ์คํฌ๋ฆฝํธ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค.
- Mocha: Chai(๋จ์ธ) ๋ฐ Sinon.JS(๋ชจ์)์ ์์ฃผ ํจ๊ป ์ฌ์ฉ๋๋ ์ ์ฐํ ํ ์คํธ ํ๋ ์์ํฌ์ ๋๋ค.
- Chai: ๋ค์ํ ๋จ์ธ ์คํ์ผ(์: should, expect, assert)์ ์ ๊ณตํ๋ ๋จ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Sinon.JS: ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ํ ๋ ๋ฆฝํ ํ ์คํธ ์คํ์ด, ์คํ ๋ฐ ๋ชจ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- React Testing Library: ๊ตฌํ ์ธ๋ถ ์ฌํญ๋ณด๋ค๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ด์ ์ ๋ง์ถ ํ ์คํธ๋ฅผ ์์ฑํ๋๋ก ๊ถ์ฅํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Vue Test Utils: Vue.js ์ปดํฌ๋ํธ๋ฅผ ์ํ ๊ณต์ ํ ์คํธ ์ ํธ๋ฆฌํฐ์ ๋๋ค.
- Angular Testing Library: ์ต๊ทค๋ฌ ์ปดํฌ๋ํธ๋ฅผ ์ํ ์ปค๋ฎค๋ํฐ ์ฃผ๋ ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Storybook: UI ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ๊ฐ๋ฐํ๊ณ ์ ๋ณด์ด๋ ๋๊ตฌ๋ก, ํ ์คํธ ํ๋ ์์ํฌ์ ํตํฉํ ์ ์์ต๋๋ค.
- Istanbul: ๋จ์ ํ ์คํธ๋ก ์ปค๋ฒ๋๋ ์ฝ๋์ ๋น์จ์ ์ธก์ ํ๋ ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ๋๊ตฌ์ ๋๋ค.
์ค์ ์ฌ๋ก
์ค์ ์๋๋ฆฌ์ค์์ ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ฅผ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ช ๊ฐ์ง ์ค์ฉ์ ์ธ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
์์ 1: ํผ ์ ๋ ฅ ์ปดํฌ๋ํธ ํ ์คํธํ๊ธฐ
ํน์ ๊ท์น(์: ์ด๋ฉ์ผ ํ์, ๋น๋ฐ๋ฒํธ ๊ฐ๋)์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ ๋ ฅ์ ๊ฒ์ฆํ๋ ํผ ์ ๋ ฅ ์ปดํฌ๋ํธ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ํ ์คํธํ๋ ค๋ฉด API ํธ์ถ์ด๋ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ ์ธ๋ถ ์ข ์์ฑ์ ๋ชจ์(mock)ํด์ผ ํฉ๋๋ค.
๋ค์์ React์ Jest๋ฅผ ์ฌ์ฉํ ๊ฐ๋จํ ์์ ์ ๋๋ค:
// FormInput.jsx
import React, { useState } from 'react';
function FormInput({ validate, onChange }) {
const [value, setValue] = useState('');
const handleChange = (event) => {
const newValue = event.target.value;
setValue(newValue);
onChange(newValue);
};
return (
);
}
export default FormInput;
// FormInput.test.jsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import FormInput from './FormInput';
describe('FormInput Component', () => {
it('should update the value when the input changes', () => {
const onChange = jest.fn();
render( );
const inputElement = screen.getByRole('textbox');
fireEvent.change(inputElement, { target: { value: 'test value' } });
expect(inputElement.value).toBe('test value');
expect(onChange).toHaveBeenCalledWith('test value');
});
});
์ด ์์ ์์๋ ์
๋ ฅ์ด ๋ณ๊ฒฝ๋ ๋ ์ฌ๋ฐ๋ฅธ ๊ฐ์ผ๋ก ํธ์ถ๋๋์ง ํ์ธํ๊ธฐ ์ํด onChange
prop์ ๋ชจ์(mocking)ํ๊ณ ์์ต๋๋ค. ๋ํ ์
๋ ฅ ๊ฐ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์
๋ฐ์ดํธ๋์๋์ง๋ ๋จ์ธํ๊ณ ์์ต๋๋ค.
์์ 2: API๋ฅผ ํธ์ถํ๋ ๋ฒํผ ์ปดํฌ๋ํธ ํ ์คํธํ๊ธฐ
ํด๋ฆญ ์ API ํธ์ถ์ ํธ๋ฆฌ๊ฑฐํ๋ ๋ฒํผ ์ปดํฌ๋ํธ๋ฅผ ์๊ฐํด ๋ณด์ธ์. ์ด ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ํ ์คํธํ๋ ค๋ฉด ํ ์คํธ ์ค์ ์ค์ ๋คํธ์ํฌ ์์ฒญ์ ํผํ๊ธฐ ์ํด API ํธ์ถ์ ๋ชจ์(mock)ํด์ผ ํฉ๋๋ค.
๋ค์์ React์ Jest๋ฅผ ์ฌ์ฉํ ๊ฐ๋จํ ์์ ์ ๋๋ค:
// Button.jsx
import React from 'react';
import { fetchData } from './api';
function Button({ onClick }) {
const handleClick = async () => {
const data = await fetchData();
onClick(data);
};
return (
);
}
export default Button;
// api.js
export const fetchData = async () => {
// API ํธ์ถ ์๋ฎฌ๋ ์ด์
return new Promise(resolve => {
setTimeout(() => {
resolve({ data: 'API data' });
}, 500);
});
};
// Button.test.jsx
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import Button from './Button';
import * as api from './api';
jest.mock('./api');
describe('Button Component', () => {
it('should call the onClick prop with the API data when clicked', async () => {
const onClick = jest.fn();
api.fetchData.mockResolvedValue({ data: 'mocked API data' });
render();
const buttonElement = screen.getByRole('button', { name: 'Click Me' });
fireEvent.click(buttonElement);
await waitFor(() => {
expect(onClick).toHaveBeenCalledWith({ data: 'mocked API data' });
});
});
});
์ด ์์ ์์๋ api.js
๋ชจ๋์ fetchData
ํจ์๋ฅผ ๋ชจ์(mocking)ํ๊ณ ์์ต๋๋ค. jest.mock('./api')
๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฒด ๋ชจ๋์ ๋ชจ์(mock)ํ๊ณ , api.fetchData.mockResolvedValue()
๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ์(mocked) ํจ์์ ๋ฐํ ๊ฐ์ ์ง์ ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ฒํผ์ ํด๋ฆญํ์ ๋ ๋ชจ์(mocked) API ๋ฐ์ดํฐ์ ํจ๊ป onClick
prop์ด ํธ์ถ๋๋์ง ๋จ์ธํ๊ณ ์์ต๋๋ค.
๊ฒฐ๋ก : ์ง์ ๊ฐ๋ฅํ ํ๋ก ํธ์๋๋ฅผ ์ํด ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ ์์ฉํ๊ธฐ
๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ๋ ๊ฒฌ๊ณ ํ๊ณ , ์ ์ง๋ณด์ ๊ฐ๋ฅํ๋ฉฐ, ํ์ฅ ๊ฐ๋ฅํ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ํ์์ ์ธ ๊ดํ์ ๋๋ค. ์ปดํฌ๋ํธ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ํ ์คํธํจ์ผ๋ก์จ ๊ฐ๋ฐ ์ฃผ๊ธฐ ์ด๊ธฐ์ ๋ฒ๊ทธ๋ฅผ ์๋ณํ๊ณ ์์ ํ๋ฉฐ, ์ฝ๋ ํ์ง์ ํฅ์์ํค๊ณ , ๊ฐ๋ฐ ์๊ฐ์ ๋จ์ถํ๋ฉฐ, ์ฝ๋ ๋ณ๊ฒฝ์ ๋ํ ์์ ๊ฐ์ ๋์ผ ์ ์์ต๋๋ค. ํผํด์ผ ํ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ํจ์ ์ด ์์ง๋ง, ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ์ ์ด์ ์ ์ด๋ ค์์ ํจ์ฌ ๋ฅ๊ฐํฉ๋๋ค. ๋จ์ ํ ์คํธ์ ๋ํ ์ผ๊ด๋๊ณ ์ฒด๊ณ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ฑํํจ์ผ๋ก์จ ์๊ฐ์ ์ํ์ ๊ฒฌ๋ ์ ์๋ ์ง์ ๊ฐ๋ฅํ ํ๋ก ํธ์๋๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ํ ์คํธ๋ฅผ ๊ฐ๋ฐ ํ๋ก์ธ์ค์ ํตํฉํ๋ ๊ฒ์ ๋ชจ๋ ํ๋ก์ ํธ์ ์ฐ์ ์์๊ฐ ๋์ด์ผ ํ๋ฉฐ, ์ด๋ ์ ์ธ๊ณ ๋ชจ๋ ์ฌ๋์๊ฒ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ ๊ฒ์ ๋๋ค.
๊ธฐ์กด ํ๋ก์ ํธ์ ๋จ์ ํ ์คํธ๋ฅผ ํตํฉํ๋ ๊ฒ๋ถํฐ ์์ํ์ฌ ๊ธฐ์ ๊ณผ ๋๊ตฌ์ ์ต์ํด์ง๋ฉด์ ์ ์ฐจ ๊ฒฉ๋ฆฌ ์์ค์ ๋์ฌ๊ฐ์ธ์. ์ผ๊ด๋ ๋ ธ๋ ฅ๊ณผ ์ง์์ ์ธ ๊ฐ์ ์ด ๊ฒฉ๋ฆฌ๋ ๋จ์ ํ ์คํธ ๊ธฐ์ ์ ๋ง์คํฐํ๊ณ ๊ณ ํ์ง ํ๋ก ํธ์๋๋ฅผ ๊ตฌ์ถํ๋ ์ด์ ์์ ๊ธฐ์ตํ์ธ์.