์ข์ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ
by JiwonDevํ ์คํธ๋ ์ํํธ์จ์ด ํ๋ก์ ํธ์์ ๋น ์ง๋ฉด ์๋๋ ํ์ ์์์ด๋ค.
ํ์ง๋ง ์ปจํธ๋กค๋ฌ์ ์๋ ๋จ 3์ค์ ์ฝ๋๋ฅผ ์ํด ๋ฐ๋ณต๋๋ ํ ์คํธ๋ฅผ ์์ฑํ๊ณ , ํ ์คํธ์ ํ์ํ ๋ณต์กํ ์์กด๊ด๊ณ๋ฅผ ํ๋ํ๋ ๋ง๋ค๋ค๋ณด๋ฉด ๋ฌด์ธ๊ฐ ์๋ชป๋์๋ค๋ ์ ํธ๋ฅผ ๋ชธ์ผ๋ก ๋๋ผ๊ฒ ๋๋ค.
ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋๊ตฌ์๊ฒ๋ ์ฌ๋ฏธ์๊ณ ๊ท์ฐฎ์ ๋ฐ๋ณต์์ ์ด๋ค.
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ํ ์คํธ๋ ํ์ํ๋ค.
- ์ด์์์์ ์ฅ์ ๋ฅผ ๊ฒช๊ฑฐ๋, ํ ์คํธ๋ฅผ ์์ฑํ๋ค๋ฉด ํ์ง ์์์ ์ค์๋ค
- ํ ์คํธ๋ฅผ ์์ฑํ๋ฉด์ ๋์ด์ง๋ ์ค๊ณ์ ๋ํ ์์ผ์ ๋ฆฌํฉํ ๋ง ๊ณผ์
- ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ ๊ธฐ์กด ์ฝ๋์ ์์ ์ ๋๋ ต์ง ์๊ฒ ๋ง๋ค์ด์ฃผ๋ ์์ ์ฅ์น
๐ญ ํ ์คํธ์ ๋ชฉ์
์ ์ฉ ํ๋ ์์ํฌ๋ Mock ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ์ด๋ค๊ณ ์ข์ ํ ์คํธ์ธ๊ฒ ์๋๋ค. ์คํ๋ ค ํ ์คํธ์ ์ ํ ํ์์์ ์๋ ์๋ค.
ํ ์คํธ๋ฅผ ์์ฑํจ์ผ๋ก์ ์ป๋ ์ด๋๊ณผ ๋ค์ด๊ฐ๋ ๋ ธ๋ ฅ์ ํญ์ ๊ณ ๋ คํด์ผํ๊ณ , ํ ์คํธ์ ๋๋ ๋ ธ๋ ฅ์ ์ต์ํ ํด์ผํ๋ค.
์๋ฅผ ๋ค์ด ์ค๋๋ ๊ธฐ์กด์ฝ๋๋ฅผ ์ ๋ถ ๋ฏ์ด๊ฐ๋ฉฐ ํ ์คํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฑด ์ข์ง์๋ค. ์ด๋ ํฌ์ ๋๋น ์์ฐ์ฑ์ด ์ ํ ์๊ธฐ ๋๋ฌธ.
์๋์ ๊ฐ์ ์กฐ๊ฑด์ ๊ธฐ์ ์ฉ ์ฑ์ ์์ฑํ ๋, ํ ์คํธ์ ํจ์จ์ ๊ทน๋ํํ๋ ค๋ฉด ์ด๋ป๊ฒ ์์ฑํด์ผํ ๊น?
- ๋์ ๋น์ฆ๋์ค ๋ณต์ก๋
- ๊ธด ํ๋ก์ ํธ ์๋ช , ์ ์ง๋ณด์ ๊ธฐ๊ฐ
- ์ค๊ฐ ํฌ๊ธฐ์ ๋ฐ์ดํฐ ๊ด๋ฆฌ
- ๋ฎ๊ฑฐ๋ ์ค๊ฐ ์ ๋์ ์ฑ๋ฅ ์๊ตฌ
๐ ๋ฌด์์ด ์ข์ ํ ์คํธ๋ฅผ ๋ง๋ค๊น?
์ฐ์ , ํํ ์ฌ์ฉํ๋ ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง 100%๋ ์ข์ ํ ์คํธ๋ฅผ ๋ณด์ฅํ์ง ์๋๋ค.
ํ์๊ฐ์ ํฉ์์์ด ๋ฌด์์ ๋์ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๊ณ ์ง ๋ถ๋ฆฐ๋ค๋ฉด, ์๋์ ๊ฐ์ ์ด์ด์๋ ํ ์คํธ๊ฐ ๋์ฌ์ง๋ ๋ชจ๋ฅธ๋ค.
int add(int a, int b){
return a - b;
}
@Test
@DisplayName("add ํจ์๋ ๋ ์ ์๋ฅผ ๋ํด์ ์ ์ํ์ผ๋ก ๋ฐํํ๋ค.")
void test(){
// ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ต์ง๋ก ์ฑ์ฐ๊ธฐ ์ํด์ ์ ํ ๊ฒ์ฆ๋์ง ์๋ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
assertThat(add(0, 0)).isEqualTo(0);
assertThat(add(1, 0)).isEqualTo(1);
}
์ฐ๋ฆฌ๋ ํ ์คํธ์ ๋์์ ์ง์คํ๊ณ , ๊ทธ ๋์์ ๊ฒ์ฆํด์ผํ๋ค.
์ปค๋ฒ๋ฆฌ์ง๋ ๋ถ์ ์งํ๋ก ์ฌ์ฉํด์ผํ๋ค. ๋๋ฌด ๋ฎ์ผ๋ฉด ํ์คํ๊ฒ ์์ข์ ์ฝ๋์ง๋ง, ๋๋ค๊ณ ๋ฌด์กฐ๊ฑด ์ข์ ๊ฑด ์๋๋ค.
๋ณ์์์ ํ์์ ์ฒด์จ์ด ๋์ผ๋ฉด ์ด์ด ๋๋ค๋ ๊ฒ์ด๊ณ , ์ด ์์น๋ฅผ ์ด์ฉํด ํ์์ ์ํฉ์ ํ์ธ ํ ์ ์๋ค.
๊ทธ๋ฌ๋ 'ํ์'๊ฐ ์๋๋ผ 'ํ์์ ๋ฎ์ ์ฒด์จ'์ด ๋ชฉํ๊ฐ ๋์ด๋ฒ๋ฆฌ๋ฉด ์ ๋ ์๋๋ค.
์ฝ์ด๋ ์น๋ฃ๋ ์น์๋ฒ๋ฆฌ๊ณ ๋น์ฅ ํ์์์ ์์ด์ปจ์ ์ค์นํ๋๊ฒ ๊ฐ์ฅ ์ข์ ์ฝ๋๊ฐ ๋์ด๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฒฐ๊ตญ ์ข์ ํ ์คํธ๋ผ๋ ๊ฑด
- ๋ฐ๋ก ์๊ฐ๋ด์ ์์ฑํ๋๊ฒ ์๋๋ผ, ๊ฐ๋ฐ ์ฃผ๊ธฐ์ ํตํฉ์์ด์ผ ํ๋ค.
- ์ฝ๋๋ฒ ์ด์ค์์ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ(ํต์ฌ ๋์)๋ง์ ํ
์คํธ ํ๋ค.
ํ ์คํธํ ๋์์ด ์๋ ๊ฒ โก ์ธํ๋ผ, ์ธ๋ถ์์คํ (DB, ์๋ํํฐ, ๋ผ์ด๋ธ๋ฌ๋ฆฌ), ๋ชจ๋ ๊ฒ์ ํ๋๋ก ๋ฌถ๋ ํตํฉ์ฝ๋ - ์ต์ํ์ ์ ์ง๋น๋ก ์ต๋์ ๊ฐ์น๋ฅผ ๋์ด๋ด์ผ ํ๋ค.
์๋ฌด๋ฐ ๊ฒ์ฆ๋ ํ์ง์๊ณ , ์ด๋ ํ ๊ฐ์น๋ ๋ง๋ค์ด ๋ด์ง์๋ ์ฝ๋. ๊ทธ์ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ฑ์ฐ๊ธฐ ์ํ ํ ์คํธ๋ ํ์์๋ค.
๐ญ ๋จ์ ํ ์คํธ
- ์์ ์ฝ๋ ๋จ์๋ฅผ
- ๋น ๋ฅด๊ฒ ํ ์คํธ๋ฅผ ์ํํ ์ ์๊ณ
- ๊ฒฉ๋ฆฌ๋ ๋ฐฉ์์ผ๋ก ์๋ํํ๋ ํ ์คํธ
์ฐ๋ฆฌ๋ ํ ์คํธํ๋ ๋์์ ์ง์คํด์ผํ๊ณ , ๋ค๋ฅธ ์ธ๋ถ์ ๋ฌธ์ ๊ฐ ์ํฅ๋ผ์น์ง ์๊ฒ ๊ฒฉ๋ฆฌํด์ผํ๋ค.
๊ฐ์ฒด์งํฅ์ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ค์ ์๋ก ๋ค๋ฅธ ์์กด์ฑ(ํ๋ ฅ)์ ํตํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
ํ
์คํธ๋ฅผ ํ๊ฒ ๋ต์๊ณ ๋ชจ๋ ์์กด์ฑ์ ๋ค ๋ง๋ค์ ์๋ค. ์์กด์ฑ์ ๋์ ํด์ค ๋จ์ ํ
์คํธ์ ๋์ญ(Test Double)์ด ํ์ํ๋ค.
์ฌ๋ด์ผ๋ก, ๊ฐ์ฒด์งํฅ์ ์ธ ์ฝ๋๋ ํ
์คํธํ๊ธฐ๋ ์ข๋ค. ๊ตฌํ ์ฝ๋๋ฅผ ๋ชฐ๋ผ๋ ๋ค๋ฅธ ๊ฐ์ฒด์ '๋ฉ์์ง'๋ฅผ ๋ณด๋ด๋ฉด ๋๊ธฐ ๋๋ฌธ.
public class FakeObject {
Map<Integer, Object> database = new HashMap<>();
int count = 0;
public Object get(int key) {
return database.get(key);
}
public void save(Object data) {
database.put(count++, data);
}
public int getCount(){
return 10; // ํ
์คํธ์ฉ Stub ๊ฐ
}
}
์ข์ ํ ์คํธ์ ์ ํ ๊ฐ์น์๋ ํ ์คํธ๋ ํ์คํ๊ฒ ๊ตฌ๋ถํ ์ ์๋ค.
๋ด๊ฐ ์ ํ๊ณ ์๋๊ฑด๊ฐ ๊ถ๊ธํ๋ค๋ฉด, ํ ์คํธ๋ฅผ ์์ฑํ ๋ ์๋์ ํน์ฑ์ ์ ์งํค๊ณ ์๋์ง ๊ณ ๋ คํด๋ณด์.
- ํ๊ท๋ฐฉ์ง
- ๋ฆฌํฉํฐ๋ง ๋ด์ฑ
- ๋น ๋ฅธ ํผ๋๋ฐฑ๊ณผ ์ ์ง๋ณด์์ฑ
๐ ํ๊ท๋ฐฉ์ง
ํ๊ท๋ ์ผ์ข ์ ์ํํธ์จ์ด ๋ฒ๊ทธ์ด๋ค.
์ ํํ๋ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ ๋, ์๋ํ ๋๋ก ์๋ํ์ง ์์ ์ด๋ฏธ ์์ฑ๋ ์ฝ๋๋ฅผ ์์ ํ๋ ค๊ณ ๋์๊ฐ๋ ๊ฒ.
ํ๋ก์ ํธ๊ฐ ์ปค์ง๋ฉด์ ์ํํธ์จ์ด์ ๋ณต์ก๋๋ ์ ๋ง ๋น ๋ฅด๊ฒ ์ฆ๊ฐํ๋ค. ์ด๋ฌํ ํ๊ท๋ฅผ ๋ฐฉ์งํ๊ณ ์ ๋ฏธ๋ฆฌ ํ ์คํธ ํด์ผํ๋ค.
ํ ์คํธ๋ฅผ ํต๊ณผํ๋๋ฐ ๊ธฐ๋ฅ์ ๊ณ ์ฅ๋๋ ๊ฑฐ์ง์์ฑ(False Nagative)์ ๋ง๋ค์ง ๋ง์. ํ๊ทํ์ง ์๋๋ก ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ํ ์คํธ๋ก ๊ฒ์ฆํ์.
์ฌ๊ธฐ์ ์ค์ํ ๊ฒ์, `ํ๊ทํ์ง ์๋๋ก` ํ ์คํธ๋ก ๊ฒ์ฆํ๋ ๊ฒ์ด๋ค. ํ๊ท ์ค๋ฅ๊ฐ ์๊ธธ์ผ์ด ์๋ ์ฝ๋๋ฅผ ํ ์คํธํ์ง๋ ๋ง์. ์๋ฅผ ๋ค์ด User.getName() ์ฒ๋ผ ์๋ฌด๋ฐ ๋ก์ง์ด ์๋ ์ฝ๋๋ฅผ ํ ์คํธํ๋ ๊ฒ์ ์๋ฌด๋ฐ ๊ฐ์น๊ฐ ์๋ค.
๐ ๋ฆฌํฉํฐ๋ง ๋ด์ฑ
ํ ์คํธ๋ ์ฝ๋ ๋ฆฌํฉํฐ๋ง์ ๋ด์ฑ์ด ์์ด์ผํ๋ค.
์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ณ , ๋ชจ๋ ๊ฒ์ด ์ ๋์ํ๋๋ฐ ๊ธฐ์กด ํ ์คํธ๊ฐ ๊นจ์ง๋ฉด ์๋๋ค. ์ด๋ฌํ ํ์ ๊ฒฝ๋ณด๋ ํ ์คํธ์ ๊ฐ์น๋ฅผ ๋จ์ด๋จ๋ฆฌ๊ณ ๊ฒฐ๊ตญ ๊ฐ๋ฐ์๋ ํ ์คํธ ์์ ์ ํผํ๊ธฐ์ํด์ ์ฝ๋ ๋ณ๊ฒฝ์ ์ต์ํํ๋ ค๊ณ ํ๊ฒ๋๋ค.
ํ ์คํธ๊ฐ ๋ฆฌํฉํ ๋ง์ ๋ด์ฑ์ด ์์ผ๋ ค๋ฉด ์ด๋ป๊ฒ ์ฝ๋๋ฅผ ์์ฑํด์ผํ ๊น?
๊ฐ๋จํ๋ค. ๊ตฌํ ์ธ๋ถ์ฌํญ์ด ์๋, ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ํ ์คํธ ๋ชฉํ๋ก ์ผ์ผ๋ฉด ๋๋ค.
ํ๊ท๋ฐฉ์ง์์๋ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ํ ์คํธํ๋ผ๊ณ ํ๋ค. ๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ ํ์ง๋ง๋ผ๊ณ ? ๊ทธ๊ฒ ์๋๋ค. ์กฐ๊ธ ๋ ์๊ฐํด๋ณด์.
ํ์๊ฐ์ ์ ํ ๋ ๋น๋ฐ๋ฒํธ์ PasswordEncoder ๊ฐ์ ๋ด๋ถ ์๊ณ ๋ฆฌ์ฆ์ด ๋ฐ๋์๋ค๊ณ ํ ์คํธ ๊ฒฐ๊ณผ์ ์ํฅ์ด ์์๊น?
์ฌ์ค ํ ์คํธ๋ฅผ ํ ๋ ๊ทธ ๊ฐ์ฒด์ ๋ด๋ถ ๋์๊น์ง ์ ํ์๋ ์๋ค. ๊ณต๊ฐ๋ ๋์(api)์ ์คํํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ง ํ์ธํ๋ฉด ๋๋ค.
๋ฐ๋๋ก ๋งํ๋ฉด, ๊ตฌํ์ ์ธ๋ถ์ฌํญ์ด ๋ณํ์ ๋ ํ ์คํธ๊ฐ ๊นจ์ง ์ ์๋ค๋ฉด, ๊ด์ฐฎ์๋ณด์ด์ง๋ง ์๋ชป๋ ๊ฑฐ์ง์์ฑ(False Positive) ํ ์คํธ๊ฐ ์๋๊ฐ ์์ฌํด์ผํ๋ค. [์ฌ์ค ๋ฆฌํฉํฐ๋ง ๋ด์ฑ์ ํ๋ก์ ํธ ์ด๋ฐ์๋ ํฐ ๋ฌธ์ ๊ฐ ๋์ง ์๋๋ค.]
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ํ๊ท๋ฐฉ์ง๋ ์๊ฒ๋ชจ๋ฅด๊ฒ ํ๊ณ ์์ง๋ง, ๋ฆฌํฉํฐ๋ง ๋ด์ฑ(๊ฑฐ์ง ์์ฑ)์๋ ๋๊ฐํ ์ฌ๋๋ค์ด ๋ง๋ค.
๊ทธ ์ด์ ๋ ํ๋ก์ ํธ ์ด๊ธฐ์๋ ๊ฑฐ์ง์์ฑ์ด ํฐ ๋ฌธ์ ๊ฐ ๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋น์ฅ์ ๋ฆฌํฉํ ๋งํ๋๊ฒ ๋ ์ฌ์ฐ๋๊น.
ํ์ง๋ง ํ๋ก์ ํธ๊ฐ ์ปค์ง๋ฉด ์ปค์ง์๋ก ๋ฆฌํฉํ ๋ง ๋ด์ฑ์ ์ค์ํด์ง๋ค. ๊ธฐ๋ฅ ๊ณ ์ฅ์ด ์๋๋ฐ๋ ํ ์คํธ๊ฐ ๊ณ์ ๊นจ์ง๋ฉด์ ํ ์คํธ์ ๋ํ ์ ๋ขฐ๋ฅผ ์๊ฒ๋๊ณ , ๊ฐ๋ฐ์๋ ์๋ฌด๊ฐ์ ์์ฑํ๋ ๊ฐ์น์๋ ํ ์คํธ๋ฅผ ๊ณ์ ์์ฑํ๊ฒ ๋๋ค.
๐ ๋น ๋ฅธ ํผ๋๋ฐฑ๊ณผ ์ ์ง๋ณด์์ฑ
๋น ๋ฅธ ํผ๋๋ฐฑ ๋ํ ๋จ์ํ ์คํธ์์ ๋งค์ฐ ์ค์ํ๋ค.
๋ชจ๋ ์์กด์ฑ์ ๋ค ๊ฒ์ฌํ๋๊ฒ ์๋, ๊ทธ ๋์๋ง์ ๋น ๋ฅด๊ฒ ๊ฒ์ฆํ๊ณ ๋ฒ๊ทธ๋ฅผ ํผ๋๋ฐฑํจ์ผ๋ก์ ๋ฒ๊ทธ ์์ ๋น์ฉ์ ํฌ๊ฒ ์ค์ผ ์ ์๋ค. ์ด๋ฏธ ์ถฉ๋ถํ ๊ฒ์ฆ์ ํ๋ค๋ฉด, ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋๋ผ๋ ๊ธฐ์กด ์ฝ๋๊ฐ ๊นจ์ง์ง ์์๊น ๋๋ ค์ํ์ง ์์๋ ๋๋ค.
๋น์ทํ ๋งฅ๋ฝ์ผ๋ก, ๋จ์ํ ์คํธ๋ ์ ์ง๋ณด์์ฑ์ด ์ข์์ผ ํ๋ค.
ํ ์คํธ๋ฅผ ์ดํดํ๊ธฐ ์ฝ๊ณ ์ธ๋ถ ์์กด์ฑ์์ด ๋ฐ๋ก ์คํํ๊ธฐ ์ฝ๊ฒ ๋ง๋ฆ์ผ๋ก์ ๋์ค์ ํ ์คํธ๋ฅผ ์ถ๊ฐํ๋๋ผ๋ ํ ์คํธ์ ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๋ค.
๐ ์ด์์ ์ธ ํ ์คํธ๋ 3๊ฐ์ง๊ฐ ๊ณจ๊ณ ๋ฃจ ๊ฐ์ถฐ์ ธ์ผํ๋ค.
์ด 3๊ฐ์ง๋ ๋ฐ๋ก ๋ ธ๋ ๊ฐ๋ ๋ค์ด ์๋๋ค.
์์ผ๋ฉด ์ข๊ณ , ์์ผ๋ฉด ์ญ์ญํ ๊ทธ๋ฐ ์์๋ค์ด ์๋๊ณ ํ ์คํธ์๋ ์ด ์์๋ค์ด ๋ค ๊ณจ๊ณ ๋ฃจ ๊ฐ์ถ์ด์ ธ์์ด์ผ ํ๋ค.
#1. ๊ทน๋จ์ ์ธ ์ฌ๋ก1 : E2E(End to End) ํ ์คํธ
E2E๋ ์ต์ข ์ฌ์ฉ์ ๊ด์ ์์ ๋ชจ๋ ์์คํ ์ ์ฌ์ฉํ๋ ํ ์คํธ๋ฅผ ์๋ฏธํ๋ค.
์ด๋ ์ง์ ์์ฑํ ์ฝ๋๋ฅผ ํฌํจํ์ฌ ์ธ๋ถ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํ๋ ์์ํฌ, DB๋ฑ์ ๋ชจ๋ ํ
์คํธํ๋ค.
๋ฆฌํฉํ ๋ง ๋ด์ฑ์ ์ด๋ค๊ฐ? ์ฌ์ฉ์ ๊ด์ ์์ ํ
์คํธํ๊ธฐ ๋๋ฌธ์ ๋ด๋ถ๊ตฌํ์ ์ ํ ์ ํ์๊ฐ ์๋ค. ๊ฒฐ๊ณผ๋ง ๊ฒ์ฆํ๋ค.
- โ ํ๊ท๋ฐฉ์ง๊ฐ ์ฐ์ํ๋ค.
- โ ๋ฆฌํฉํ ๋ง ๋ด์ฑ ๋ํ ์ฐ์ํ๋ค.
๊ทธ๋ผ ๋ชจ๋ ํ ์คํธ๋ฅผ E2E๋ก ๋ง๋ค๋ฉด ์ต๊ณ ์ผํ ๋ฐ ์ ๊ทธ๋ ๊ฒ ํ์ง ๋ชปํ ๊น?
์ด์ ๋ ๋จ์ํ๋ค. ํ ์คํธ๋ฅผ ์ค๋นํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ต๊ณ ๋ชจ๋ ๊ตฌํ์ด ์๋ฃ๋์ด์ผ ํ ์คํธ๊ฐ ๊ฐ๋ฅํ๋ค.
์ฆ, ํผ๋๋ฐฑ์ด ๋๋ฌด๋๋ฆฌ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๋ค๋ฉด ์ ์ฒด์ฝ๋๋ฅผ ๋ค์ ๋ฏ์ด๋ด์ผํ๊ณ , ์ ์ฒด ๋์์ ํ๋ฒ์ ๊ฒ์ฆํ๋๊ฑฐ๋ผ ํ ์คํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋ ๋งค์ฐ ๋ถ๋ด์ด ๋๋ค.
#2 ๊ทน๋จ์ ์ธ ์ฌ๋ก2 : ๋๋ฌด ๊ฐ๋จํ ํ ์คํธ
ํผ๋๋ฐฑ์ด ๋๋ฆฌ๋ค๊ณ ? ์ข๋ค ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒ์ ํ ์คํธํด๋ณด๊ณ , ๋น ๋ฅด๊ฒ ํผ๋๋ฐฑ ๋ฐ์๋ณด์
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Test
@DisplayName("User ๊ฐ์ฒด์์ name์ ์กฐํํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.")
void Test() {
// Arrange
var sut = new User(); // sut => System under test, ํ
์คํธ ๋์ ๊ฐ์ฒด
var string = "New User Name";
// Act
sut.setName(string);
// Assert
assertThat(sut.getName()).isEqualTo(string);
}
- โ ํผ๋๋ฐฑ ์ฃผ๊ธฐ๊ฐ ๋งค์ฐ ๋น ๋ฅด๋ค.
- โ ๋ด๋ถ ๊ตฌํ์ด ์๋๋ผ ๊ณต๊ฐ๋ api๋ง ํ ์คํธ ํ๋ ๊ฒ์ด๋ฏ๋ก ๋ฆฌํฉํ ๋ง ๋ด์ฑ ๋ํ ๊ทธ๋ ๊ฒ ๋์์ง ์๋ค.
ํ์ง๋ง ๋ฌด์ธ๊ฐ ์ด์ํ๋ค๊ณ ๋๊ปด์ง๋ค. ์๋ฌด๋ฐ ๊ฐ์น๋ ์๊ณ ๋น์ทํ ํ ์คํธ๊ฐ ์๋ฐฑ๊ฐ๋ ๋ฐ๋ณต๋๋ค. ์ด๊ฑธ ์ ์์ฑํ๋ ๊ฑธ๊น?
์ด๋ ํ ์คํธ๋ฅผ ์์ฑํ ๋ ํ๊ท ๋ฐฉ์ง๋ฅผ ๊ณ ๋ คํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค. ํ ์คํธ๋ 'ํ๊ท๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด` ์์ฑํด์ผํ๋ค. ์ ํ ํ๊ท ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ ๊ฒ ๊ฐ์ ๋จ์ํ ์ฝ๋๋ฅผ ํ ์คํธ ํ ํ์๊ฐ ์๋ค.
#3. ๊ทน๋จ์ ์ธ ์ฌ๋ก3: ๊นจ์ง๊ธฐ ์ฌ์ด ํ ์คํธ
๊ทธ๋ผ ๋ง์ง๋ง์ผ๋ก ๋ฆฌํฉํ ๋ง ๋ด์ฑ์ ๋ ์ด๋จ๊น?
์ด๋ ์ํด์ ์ธ๊ธํ์ผ๋ฏ๋ก, ๊ฐ๋จํ๊ฒ ์ฝ๋๋ก๋ง ์ดํด๋ณด๊ณ ๋์ด๊ฐ๋๋ก ํ์.
@Getter
public class UserRepository() {
// ์ค์ Repository ๊ฐ์ฒด
private String lastExecutedSqlStatement();
}
@Test
@DisplayName("UserRepository ๊ฐ์ฒด์ getById ๋ฉ์๋๋ ์ฌ๋ฐ๋ฅธ SQL๋ฌธ์ ์์ฑํ๋ค. ")
void Test() {
// Arrange
var sut = new UserRepository();
// Act
User user = sut.getById(5);
// Assert
Assertions.assertThat(sut.getLastExecutedSqlStatement)
.isEqualTo("SELECT * FROM dbo.[User] WHERE UserId = 5");
}
๋ง์ฝ DB๋ฅผ ํ๋ํ๊ฒ๋์ด SQL๋ฌธ์ด ๋ณ๊ฒฝ๋๊ฑฐ๋, ์ง์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ์ง์๊ณ ORM์ ์ฌ์ฉํ๊ฒ ๋ณ๊ฒฝ๋๋ค๋ฉด ์ด๋จ๊น?
ํ ์คํธ๋ ํต์ฌ ๋์์ ํ ์คํธํ๋๊ฑฐ์ง ๋ด๋ถ ๊ตฌํ์ฌํญ์ ๋ชฐ๋ผ๋ ํฐ ์๊ด์ด ์๋ค. ์ธ๋ถ์ฌํญ์ ํ ์คํธํ๋ฉด ์๋๋ค.
ํ์๊ฐ์ ์ ํ๋๋ฐ DB๋ passwordEncoder ์๊ณ ๋ฆฌ์ฆ์ด ๋ฐ๋์ด๋ ๋์์๋ ์๋ฌด๋ฐ ์ํฅ์ด ์๋ค.
ํ์ง๋ง ํ์๊ฐ์ ํ ์คํธ๋ ์ ๋ถ ์คํจํ ๊ฒ์ด๋ค. ๋ฆฌํฉํ ๋ง ๋ด์ฑ์ด ์ ํ ์๋ ํ ์คํธ๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ด๋ค.
๐ญ ๊ฒฐ๋ก
๋ง์ ์ด๋ ๊ฒ ํ์ด๋, ๋ชจ๋ ์กฐ๊ฑด์ ์๋ฒฝํ๊ฒ ์ถฉ์กฑํ๋ ํ ์คํธ๋ฅผ ์์ฑํ๊ธฐ๋ ์ฝ์ง ์๋ค.
ํ์ ์ฃผ์๋ฉด ๋๋ถ๋ถ์ ๊ธฐ์ ์ฉ ํ๋ก์ ํธ์์๋ ๋ฆฌํฉํฐ๋ง ๋ด์ฑ์ ํฌ๊ธฐํ ์ ์๋ค. ๋ฆฌํฉํฐ๋ง ๋ด์ฑ์ ์ค์ ์๋น์ค์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋๋ฐ ํฐ ์ํฅ์ ๋ผ์น๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฆฌํฉํ ๋ง ๋ด์ฑ์ ๊ฐ์ฅ ์ค์ํ๊ฒ ๊ณ ๋ คํ๊ณ , ํ๊ท ๋ฐฉ์ง์ ๋น ๋ฅธ ํผ๋๋ฐฑ์ ์ ์ ํ๊ฒ ํํํ๋๊ฒ ์ข๋ค.
๋ค๋ง ์ ์ถฉ์์ ์ ํํ๋๊ฑฐ์ง, ์ ๊ทน๋จ์ ์ธ ์ฌ๋ก์ฒ๋ผ ํ์ชฝ์ ์์ ํ ํฌ๊ธฐํด์๋ ์ ๋ ์๋๋ค. ์ข์ ํ ์คํธ๋ ์ธ์ ๋ 3๊ฐ์ง ์์๋ฅผ ๋ค ๊ณ ๋ คํด์ผํ๋ค.
ํ ์คํธ์ ๋ณธ์ง์ ์ธ ๋ชฉ์ ์ ์์ง ๋ง์.
'๐ฑ Spring Framework > Test (JUnit, SpringBootTest)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ ์คํธ ๋ฐ์ดํฐ๋๊ตฌ - Fixture Monkey (3) | 2022.04.02 |
---|---|
spring security ํ ์คํธ์ฉ ์ค์ ๋ฐฉ๋ฒ (1) | 2022.03.07 |
Spring Boot Test์ ์ฌ๋ผ์ด์ค ํ ์คํธ (0) | 2021.09.08 |
์๋ฐ ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ - JUnit5, AssertJ (0) | 2021.09.07 |
๋ค์ํ ํ ์คํธ์ Test Double (+Mockist) (0) | 2021.09.07 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev