0523 ~ 0605
# 0523 ~ 0605
# 0525 - ๋จ์ ํ ์คํธ, ํตํฉ ํ ์คํธ, ์ธ์ ํ ์คํธ
# ๋จ์ ํ ์คํธ (Unit Test)
๋จ์ ํ ์คํธ๋ ์์ฉ ํ๋ก๊ทธ๋จ์์ ํ ์คํธ ๊ฐ๋ฅํ ๊ฐ์ฅ ์์ ์ํํธ์จ์ด๋ฅผ ์คํํ์ฌ ์์๋๋ก ๋์ํ๋์ง ํ์ธํ๋ ํ ์คํธ
๋จ์ ํ ์คํธ์์ ํ ์คํธ ๋์ ๋จ์์ ํฌ๊ธฐ๋ ์๊ฒฉํ๊ฒ ์ ํด์ ธ ์์ง ์๋ค. ํ์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก ํด๋์ค ๋๋ ๋ฉ์๋ ์์ค์ผ๋ก ์ ํด์ง๋ค. ๋จ์์ ํฌ๊ธฐ๊ฐ ์์์๋ก ๋จ์์ ๋ณต์ก์ฑ์ด ๋ฎ์์ง๋ค. ๋ฐ๋ผ์, ๋จ์ ํ ์คํธ๋ฅผ ํ์ฉํ์ฌ ๋์์ ํํํ๊ธฐ ๋ ์ฌ์์ง๋ค. ์ฆ, ํ ์คํธ ๋์ ๋จ์์ ํฌ๊ธฐ๋ฅผ ์๊ฒ ์ค์ ํด์ ๋จ์ ํ ์คํธ๋ฅผ ์ต๋ํ ๊ฐ๋จํ๊ณ ๋๋ฒ๊น ํ๊ฒ ์ฝ๊ฒ ์์ฑํด์ผ ํ๋ค.
์ํํธ์จ์ด๋ฅผ ๊ฐ๋ฐํ ๋, ์ํํธ์จ์ด ๋ด๋ถ ๊ตฌ์กฐ๋ ๊ตฌํ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ์ฌ ๊ฐ๋ฐ์๊ด์ ์์ ํ ์คํธํ๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋จ์ ํ ์คํธ๋ ์ํํธ์จ์ด ๋ด๋ถ ์ฝ๋์ ๊ด๋ จํ ์ง์์ ๋ฐ๋์ ์๊ณ ์์ด์ผ ํ๋ ํ์ดํธ๋ฐ์ค ํ ์คํธ์ด๋ค. ๋จ์ ํ ์คํธ๋ TDD์ ํจ๊ป ํ ๋ ํนํ ๋ ๊ฐ๋ ฅํด์ง๋ค.
@DisplayName("์๋์ฐจ๊ฐ ์ ์งํ๋ค")
@Test
public void moveCar() {
// given
Car car = new Car("dani");
// when
car.move(4);
// then
assertThat(car.getPosition()).isEqualTo(1);
}
@DisplayName("์๋์ฐจ๊ฐ ๋ฉ์ถ๋ค")
@Test
public void stopCar() {
// given
Car car = new Car("dani");
// when
car.move(3);
// then
assertThat(car.getPosition()).isEqualTo(0);
}
# ํตํฉ ํ ์คํธ (Integration Test)
ํตํฉ ํ ์คํธ๋ ๋จ์ ํ ์คํธ๋ณด๋ค ๋ ํฐ ๋์์ ๋ฌ์ฑํ๊ธฐ ์ํด ์ฌ๋ฌ ๋ชจ๋๋ค์ ๋ชจ์ ์ด๋ค์ด ์๋๋๋ก ํ๋ ฅํ๋์ง ํ์ธํ๋ ํ ์คํธ์ด๋ค.
ํตํฉ ํ ์คํธ๋ ๋จ์ ํ ์คํธ์ ๋ฌ๋ฆฌ ๊ฐ๋ฐ์๊ฐ ๋ณ๊ฒฝํ ์ ์๋ ๋ถ๋ถ(ex. ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)๊น์ง ๋ฌถ์ด ๊ฒ์ฆํ ๋ ์ฌ์ฉํ๋ค. ์ด๋ DB์ ์ ๊ทผํ๊ฑฐ๋ ์ ์ฒด ์ฝ๋์ ๋ค์ํ ํ๊ฒฝ์ด ์ ๋๋ก ์๋ํ๋์ง ํ์ธํ๋๋ฐ ํ์ํ ๋ชจ๋ ์์ ์ ์ํํ ์ ์๋ค. ๊ทธ๋ฌ๋, ํตํฉ ํ ์คํธ๊ฐ ์์ฉ ํ๋ก๊ทธ๋จ์ด ์์ ํ๊ฒ ์๋ํ๋๊ฑธ ๋ฌด์กฐ๊ฑด ์ฆ๋ช ํ์ง๋ ์๋๋ค.
ํตํฉ ํ ์คํธ์ ์ฅ์ ์ ๋จ์ ํ ์คํธ์์ ๋ฐ๊ฒฌํ๊ธฐ ์ด๋ ค์ด ๋ฒ๊ทธ๋ฅผ ์ฐพ์ ์ ์๋ค๋ ์ ์ด๋ค. ์๋ฅผ ๋ค์ด, ํตํฉ ํ ์คํธ์์๋ ํ๊ฒฝ ๋ฒ๊ทธ(ex. ์ฑ๊ธ ์ฝ์ด CPU์์๋ ์ ์คํ๋๊ฑฐ๋ ์ฟผ๋ ์ฝ์ด CPU์์๋ ์ ์คํ๋์ง ์์)์ด ๋ฐ์ํ ์ ์๋ค.
ํํธ, ํตํฉ ํ ์คํธ์ ๋จ์ ์ ๋จ์ ํ ์คํธ๋ณด๋ค ๋ ๋ง์ ์ฝ๋๋ฅผ ํ ์คํธํ๊ธฐ ๋๋ฌธ์ ์ ํ์ฑ์ด ๋จ์ด์ง ์ ์๋ค๋ ์ ์ด๋ค. ๋, ์ด๋์ ์๋ฌ๊ฐ ๋ฐ์ํ๋์ง ํ์ธํ๊ธฐ ์ฝ์ง ์์ ์ ์ง๋ณด์ํ๊ธฐ ํ๋ค๋ค๋ ์ ๋ ์๋ค.
์คํ๋ง๋ถํธ์์๋ ํด๋์ค ์๋จ์ @SpringBootTest ์ด๋ ธํ ์ด์ ์ ๋ถ์ฌ ํตํฉ ํ ์คํธ๋ฅผ ์ํํ ์ ์๋ค.
@SpringBootTest
class SubwayApplicationTests {
@Test
void contextLoads() {
}
}
# ์ธ์ ํ ์คํธ (Acceptance Test)
์ธ์ํ ์คํธ๋ ์ฌ์ฉ์ ์คํ ๋ฆฌ(์๋๋ฆฌ์ค)์ ๋ง์ถฐ ์ํํ๋ ํ ์คํธ์ด๋ค.
์์ ๋ ํ ์คํธ๋ค๊ณผ ๋ฌ๋ฆฌ ๋น์ฆ๋์ค ์ชฝ์ ์ด์ ์ ๋๋ค. ํ๋ก์ ํธ์ ์ฐธ์ฌํ๋ ์ฌ๋๋ค์ด ํ ์ํด์ ์๋๋ฆฌ์ค๋ฅผ ๋ง๋ค๊ณ , ๊ฐ๋ฐ์๋ ์ด์ ์๊ฑฐํด์ ์ฝ๋๋ฅผ ์์ฑํ๋ค. ๊ฐ๋ฐ์๊ฐ ์ง์ ์๋๋ฆฌ์ค๋ฅผ ์ ์ํ ์๋ ์์ง๋ง, ๋ค๋ฅธ ์์ฌ์ํต์ง๋จ์ผ๋ก๋ถํฐ ์๋๋ฆฌ์ค๋ฅผ ๋ฐ์ ๊ฐ๋ฐํ๋ค๋ ์๋ฏธ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์ธ์ ํ ์คํธ๋ ์ ์์ผ ๊ฐ๋ฐ๋ก ์์ ํ์ํ๋ค. ํนํ, ์ต์คํธ๋ฆผ ํ๋ก๊ทธ๋๋ฐ(XP)์์ ์ฌ์ฉํ๋ ์ฉ์ด์ด๋ค. ์ด๋ ์๋๋ฆฌ์ค๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋์ง๋ฅผ ํ ์คํธํ๊ธฐ ๋๋ฌธ์ ํตํฉ ํ ์คํธ์๋ ๋ถ๋ฅ๊ฐ ๋ค๋ฅด๋ค. ์๋๋ฆฌ์ค์์ ์๊ตฌํ๋ ๊ฒ์ ๋๊ฐ, ์ด๋ค ๋ชฉ์ ์ผ๋ก, ๋ฌด์์ ํ๋๊ฐ์ด๋ค. ๊ฐ๋ฐ์ ํ๋ค ๋ณด๋ฉด ์ด๋ฐ ๊ธฐ๋ฅ์ API๋ฅผ ํตํด ๋๋ฌ๋๋ค. ์ธ์ ํ ์คํธ๋ ์ฃผ๋ก ์ด API๋ฅผ ํ์ธ์ธํ๋ ๋ฐฉ์์ผ๋ก ์ด๋ค์ง๋ค.
๊ฒฐ๊ตญ, ์ธ์ ํ ์คํธ๋ ์ํํธ์จ์ด ์ธ์๋ฅผ ๋ชฉ์ ์ผ๋ก ํ๋ ํ ์คํธ์ด๋ค. ์ํํธ์จ์ด๋ฅผ ์ธ์ํ๊ธฐ ์ ์ ๋ช ์ธํ ์๊ตฌ์ฌํญ(์ธ์ ์กฐ๊ฑด)๋๋ก ์ ์๋ํ๋์ง ๊ฒ์ฆ์ด ํ์ํ๋ค.
์ํํธ์จ์ด๋ฅผ ์ธ์ํ ๋, ์ํํธ์จ์ด ๋ด๋ถ ๊ตฌ์กฐ๋ ๊ตฌํ ๋ฐฉ๋ฒ์ ๊ณ ๋ คํ๊ธฐ๋ณด๋ค๋ ์ค์ ์ฌ์ฉ์ ๊ด์ ์์ ํ ์คํธํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ๋ฐ๋ผ์, ์ธ์ ํ ์คํธ๋ ์ํํธ์จ์ด ๋ด๋ถ ์ฝ๋์ ๊ด์ฌ์ ๊ฐ์ง์ง ์๋ ๋ธ๋๋ฐ์ค ํ ์คํธ์ด๋ค. ์ค์ ์ฌ์ฉ์ ๊ด์ ์์ ํ ์คํธ ํ ๋ E2E(End-to-End) ํ์์ ์ด์ฉํด์ ํ์ธํ๋ค.
Java์์๋ RestAssured, MockMvc ๊ฐ์ ๋๊ตฌ๋ฅผ ํ์ฉํ์ฌ ์ธ์ ํ ์คํธ๋ฅผ ์์ฑ ํ ์ ์๋ค.
public static ExtractableResponse<Response> ํ์_์์ฑ_์์ฒญ(MemberRequest memberRequest) {
return RestAssured
.given()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(memberRequest)
.when().post("/api/members")
.then()
.extract();
}
# 0526 - Single branch๋ก Clone ํ, ์๋ก์ด ๋ธ๋์น ์ถ๊ฐ
git์์ ๋ธ๋์น๊ฐ ๋ง์๊ฒฝ์ฐ ํน์ ๋ธ๋์น๋ง ์ถ์ ํ๋๋ก cloneํ ์ ์๋ค.
git clone -b <branch name> --single-branch <github url> <target directory>
git clone -b jaesungahn91 --single-branch https://github.com/jaesungahn91/jwp_qna
์์ ๊ฐ์ด cloneํ ํ ์๋ก์ด ๋ธ๋์น๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์๋ก์ด ๋ธ๋์น๋ฅผ ์ถ๊ฐํ ์ ์๋ค.
git remote set-branches --add origin [remote-branch]
git fetch origin [remote-branch]:[local-branch]
# 0529 - ATDD, ์ธ์ ํ ์คํธ
# ์ธ์ ํ ์คํธ(Acceptance Test)๋?
๋ช
์ธ ๋ฑ ์๊ตฌ ์ฌํญ์ด ์ถฉ์กฑ๋๋์ง ํ์ธํ๊ธฐ ์ํด ๋น์ฆ๋์ค ์ธก๋ฉด์ ์ด์ ์ ๋ง์ถ ํ
์คํธ๋ผ๊ณ ์๊ฐํ ์ ์๋ค. ๋ณดํต ๋ง์ง๋ง ๋จ๊ณ์์ ์์
(๊ธฐ๋ฅ)์ด ์์ ํ ์๋ฃ๋์๋์ง ๊ฒ์ฌํ๋๋ฐ ์ํ๋๋ค.
์๊ตฌ์ฌํญ(์ธ์ ์กฐ๊ฑด)์ด ๋ง์กฑํ๋์ง ํ์ธํ๋ ๊ณผ์ ์์, ์๋๋ฆฌ์ค์ ๋ง์ถฐ ํ
์คํธ๊ฐ ์ํ๋๋ค. ์ด๋, ์ธ์ ์กฐ๊ฑด(Aceeptance Criteria)์ด ์ฌ์ฉ์ ์คํ ๋ฆฌ๋ฅผ ์๋๋ฆฌ์ค ํ์์ผ๋ก ํํ๋๋ฉฐ ์๋๋ฆฌ์ค๋ ํ๋ก์ ํธ์ ์ฐธ์ฌํ๋ ์ฌ๋๋ค(๊ฐ๋ฐ์, ๊ธฐํ์ ๋ฑ)์ ํ ์๋ฅผ ํตํด ๋์จ๋ค.
์๋๋ฆฌ์ค์ ์ค์ ์ ๋๊ฐ, ์ด๋ค ๋ชฉ์ ์ผ๋ก, ๋ฌด์์ ํ๋๊ฐ ์ด๋ค.
# ATDD, ์ธ์ ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ
์ธ์ ํ
์คํธ๋ฅผ ๋จผ์ ์์ฑํ ๋ค์ ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ํ๋ ๋ฐฉ๋ฒ
์ฌ์ฉ์(๊ณ ๊ฐ)-๊ฐ๋ฐ์-ํ
์คํฐ๊ฐ์ ์ปค๋ฎค๋์ผ์ด์
์ ๊ธฐ๋ฐํ ๊ฐ๋ฐ ๋ฐฉ๋ฒ
์ ์์ผ์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ๋ฒ๋ก ์ค ํ๋๋ก ์ฌ์ฉ์ ์คํ ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ธ์ ์กฐ๊ฑด์ ๋์ถํ์ฌ ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ์งํํ๋ ๋ฐฉ๋ฒ๋ก ์ด๋ค.
ATDD๋ฅผ ํตํด ์๊ตฌ์ฌํญ๊ณผ, ์์ ์ ์์์ ๋ฒ์๋ฅผ ๋ช ํํ๊ฒ ํ์ ํ ์ ์๋ค.
# 0531 - String.format
public static String format(String format, Object... args);
public static String format(Locale l, String format, Object... args);
String์ static ๋ฉ์๋์ธ format ๋ฉ์๋๋ ๋ฌธ์์ด์ ํ์์ ์ค์ ํ๋ ๋ฉ์๋์ด๋ค.
# 1. %d (= Integer Formatting)
- 10์ง์ integer์ ํ์์ ์ค์ ํ ๋ ์ด์ฉํ๋ค.
int i = 23;
System.out.println(String.format("%d_", i));
System.out.println(String.format("%5d_", i));
System.out.println(String.format("%-5d_", i));
System.out.println(String.format("%05d_", i));
// ์ถ๋ ฅ
23_
23_
23 _
00023_
int i = 123456789;
System.out.println(String.format("%,d_", i));
System.out.println(String.format("%,15d_", i));
System.out.println(String.format("%,-15d_", i));
System.out.println(String.format("%,015d_", i));
// ์ถ๋ ฅ
123,456,789_
123,456,789_
123,456,789 _
0000123,456,789_
# 2. %s (s= String Formatting)
- ๋ฌธ์์ด์ ํ์์ ์ค์ ํ ๋ ์ด์ฉํ๋ค.
String str = "tete";
System.out.println(String.format("%s_", str));
System.out.println(String.format("%12s_", str));
System.out.println(String.format("%-12s_", str));
System.out.println(String.format("%.2s_", str));
System.out.println(String.format("%-12.2s_", str));
System.out.println(String.format("%12.2s_", str));
// ์ถ๋ ฅ
tete_
tete_
tete _
te_
te _
te_
# 3. %f (= Floating point Formatting)
- ์ค์ํ ์ซ์ ํ์์ ์ค์ ํ ๋ ์ด์ฉํ๋ค.
double n = 123.45678;
System.out.println(3.4);
System.out.println(n);
System.out.println();
System.out.println(String.format("%f_", 3.4));
System.out.println(String.format("%f_", n));
System.out.println(String.format("%.6f_", n));
System.out.println(String.format("%15f_", n));
System.out.println(String.format("%-15f_", n));
System.out.println(String.format("%.3f_", n));
System.out.println(String.format("%.2f_", n));
System.out.println(String.format("%15.2f_", n));
System.out.println(String.format("%-15.2f_", n));
System.out.println(String.format("%015f_", n));
System.out.println(String.format("%015.2f_", n));
// ์ถ๋ ฅ
3.4
123.45678
3.400000_
123.456780_
123.456780_
123.456780_
123.456780 _
123.457_
123.46_
123.46_
123.46 _
00000123.456780_
000000000123.46_
# 4. Locale ์ค์
- ์ค๋ฒ๋ก๋ฉ๋
String.format(Locale, ํฌ๋งท, ๊ฐ);
๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ๊ตญ๊ฐ๋ณ ํฌ๋งท ์ค์ ์ด ๊ฐ๋ฅ.
int money = 35000;
Date today = new Date();
System.out.println(String.format("๏ฟฆ %,d", money));
System.out.println(String.format(Locale.GERMANY, "%,d โฌ", money));
System.out.println(String.format("%tp", today));
System.out.println(String.format(Locale.ENGLISH, "%tp", today));
// ์ถ๋ ฅ
๏ฟฆ 35,000
35.000 โฌ
์คํ
pm
# 0602 - JPA ์ฐ๊ด๊ด๊ณ ํธ์ ๋ฉ์๋
# ์ฐ๊ด๊ด๊ณ ํธ์ ๋ฉ์๋
์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ฅผ ๋งบ์ ๋์๋, ์์ชฝ ๋ชจ๋ ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ์ด์ผํ๋ค. ์ฌ์ค JPA์ ์ ์ฅ์์ ๋ณด์์ ๋์๋ ์ธ๋ํค ๊ด๋ฆฌ์(์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ)์ชฝ์๋ง ๊ด๊ณ๋ฅผ ๋งบ์ด์ค๋ค๋ฉด ์ ์์ ์ผ๋ก ์์ชฝ ๋ชจ๋์์ ์กฐํ๊ฐ ๊ฐ๋ฅํ๋ค.
Team team1 = new Team("Team1");
em.persist(team1);
Member member1 = new Member("Member1");
member1.setTeam(team1); // ์ฐ๊ด๊ด๊ณ ์ค์ member1 -> team1
ํ์ง๋ง ๊ฐ์ฒด๊น์ง ๊ณ ๋ คํ๋ค๋ฉด, ์์ชฝ ๋ค ๊ด๊ณ๋ฅผ ๋งบ์ด์ผํ๋ค.
Team team1 = new Team("Team1");
em.persist(team1);
Member member1 = new Member("Member1");
member1.setTeam(team1); // ์ฐ๊ด๊ด๊ณ ์ค์ member1 -> team1
team1.getMembers().add(member1) // ์ฐ๊ด๊ด๊ณ ์ค์ tema1 -> member1
์ฆ, ๊ฐ์ฒด์ ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ ์์ชฝ ๋ชจ๋ ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ์ด์ผ ์์ํ ๊ฐ์ฒด ์ํ์์๋ ์ ์์ ์ผ๋ก ๋์ํ๋ค.
์ด๋ ๋ฏ ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ๋ ๊ฒฐ๊ตญ ์์ชฝ ๋ชจ๋๋ฅผ ์ ๊ฒฝ์จ์ผํ๋ค. ๋ง์ฝ, setTeam๊ณผ getMembers().add๋ฅผ ๊ฐ๊ฐ ํธ์ถํ๋ฉด ์ค์๊ฐ ๋ฐ์ํ ์ ์๋ค. ๋ฐ๋ผ์ ์์ชฝ ๋ชจ๋์ ๊ด๊ณ๋ฅผ ๋งบ์ด์ฃผ๋ ๊ฒ์ ํ๋์ ์ฝ๋์ฒ๋ผ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ ํ๋ค.
public void setTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
์์ ๊ฐ์ด ํ๋ฒ์ ์๋ฐฉํฅ ๊ด๊ณ๋ฅผ ์ค์ ํ๋ ๋ฉ์๋๋ฅผ ์ฐ๊ด๊ด๊ณ ํธ์ ๋ฉ์๋
๋ผ๊ณ ํ๋ค.
ํ์ง๋ง ์์๊ฐ์ด setTeam ๋ฉ์๋๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์๋ก
member1.setTeam(team1);
member1.setTeam(team2);
์์ ๊ฐ์ด ์ฐ์์ ์ผ๋ก setTeam์ ํธ์ถํ ์ดํ team1์์ ๋ฉค๋ฒ๋ฅผ ์กฐํํ๋ฉด member1๊ฐ ์ฌ์ ํ ์กฐํ๋๋ค. team2๋ก ๋ณ๊ฒฝํ ๋ team1๊ณผ์ ๊ด๊ณ๋ฅผ ์ ๊ฑฐํ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค.
--> ์์
public void setTeam(Team team) {
if (this.team != null) { // ๊ธฐ์กด์ ์ด๋ฏธ ํ์ด ์กด์ฌํ๋ค๋ฉด
this.team.getMembers().remove(this); // ๊ด๊ณ๋ฅผ ๋๋๋ค.
}
this.team = team;
team.getMembers().add(this);
}
taem1.addMember(member1);
// Team
public void addMember(Member member) {
this.members.add(member);
member.setTeam(this);
}
# 0603 - @DirtiesContext
์คํ๋ง ๋จ์ ํ ์คํธ ์งํ์ ํ๋์ Spring Context๋ฅผ ์ฌ์ฌ์ฉํจ์ ๋ฐ๋ผ ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
@DirtiesContext
์ด๋
ธํ
์ด์
์ ํ
์คํธ๋ฅผ ์ํ ์ , ์ํ ํ, ๊ฐ ํ
์คํธ ์ผ์ด์ค๋ง๋ค ์ํํ๊ธฐ ์ ์ํํ ์ดํ์ Context๋ฅผ ์ฌ์์ฑํ๋ ์ญํ ์ ํ๋ค.
@DirtiesContext indicates that the underlying Spring ApplicationContext has been dirtied during the execution of a test (that is, the test modified or corrupted it in some mannerโโโfor example, by changing the state of a singleton bean) and should be closed. When an application context is marked as dirty, it is removed from the testing frameworkโs cache and closed. As a consequence, the underlying Spring container is rebuilt for any subsequent test that requires a context with the same configuration metadata.
You can use @DirtiesContext as both a class-level and a method-level annotation within the same class or class hierarchy. In such scenarios, the ApplicationContext is marked as dirty before or after any such annotated method as well as before or after the current test class, depending on the configured methodMode and classMode.
doc.spring.io์ ๋ฐ๋ฅด๋ฉด @DiritiesContext ApplicationContext ํ ์คํธ๋ฅผ ์คํํ๋๋์ ํ ์คํธํ๋ ์์ํฌ์ ์บ์๋ฅผ ์ ๊ฑฐํ๊ณ ๋ซ๊ฒํ๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ธฐ๋ณธ Spring Container์ ๋์ผํ ๊ตฌ์ฑ ๋ฉงํ ๋ฐ์ดํฐ๊ฐ ์๋ ์ปจํ ์คํธ๋ฅผ ํ์๋กํ๋ ํ์ ํ ์คํธ๋ฅผ ์ํด ์ฌ ๋น๋๋๋ค๊ณ ๋์์๋ค.
๋ฉ์๋๋ ํด๋์ค๋ ๋ฒจ์ ์ด๋ ธํ ์ด์ ์ ๋ถ์ด๋ ๊ฒ์ผ๋ก ๋์ํ๋ฉฐ, methodMode, classMode์ ๋ฐ๋ผ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ๋์ํ๊ฒ ์ค์ ํ ์ ์๋ค.
- ํด๋์ค์ ํ ์คํธ๊ฐ ์์ํ๊ธฐ ์ ์ context ์ฌ์์ฑ
@DirtiesContext(classMode = BEFORE_CLASS)
public class FreshContextTests {
// ํ
์คํธ ์ผ์ด์ค๋ค์ด ์๋ก์ด context์์ ์คํ๋จ
}
- ํด๋์ค์ ํ ์คํธ๊ฐ ๋ชจ๋ ๋๋ ๋ค์ context ์ฌ์์ฑ (๊ธฐ๋ณธ๊ฐ)
@DirtiesContext
public class ContextDirtyingTests {
// ํ
์คํธ ์ผ์ด์ค๊ฐ context์ @Bean์ ์ํ์ ์ํฅ์ ๋ผ์นจ
}
- ํด๋์ค์ ๋ชจ๋ ํ ์คํธ ์ผ์ด์ค๋ง๋ค ์์ํ๊ธฐ ์ด์ ์ context ์ฌ์์ฑ
@DirtiesContex(classMode = BEFORE_EACH_TEST_METHOD)
public class FreshContextTests {
// ๋ชจ๋ ์ผ์ด์ค์์ ์๋ก์ด context๊ฐ ํ์ํจ
}
- ํด๋์ค์ ๋ชจ๋ ํ ์คํธ ์ผ์ด์ค๊ฐ ๋๋ ๋ ๋ง๋ค context ์ฌ์์ฑ
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
public class ContextDirtyingTests {
// ๋ชจ๋ ์ผ์ด์ค๊ฐ context์ ์ํ์ ์ํฅ์ ๋ผ์นจ
}
- ํน์ ์ผ์ด์ค๋ฅผ ์์ํ๊ธฐ ์ ์ context ์ฌ์์ฑ
@DirtiesContext(methodMode = BEFORE_METHOD)
@Test
public void testProcessWhichRequiresFreshAppCtx() {
// ์๋ก์ด context๊ฐ ํ์ํ ์ด๋ค ๋ก์ง
}
- ํน์ ์ผ์ด์ค๋ฅผ ์์ํ ์ดํ context ์ฌ์์ฑ
@DirtiesContext
@Test
public void testProcessWhichDirtiesAppCtx() {
// context์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ์ด๋ค ๋ก์ง
}
# 0605 - requireNonNull
์๋ฐ 7์ ์ถ๊ฐ๋ Objects ํด๋ ์ค์์ ์ ๊ณตํ๋ Null ์ฒดํฌ๋ฅผ ์ํ ๋ฉ์๋ ์ด๋ค. ํ๋ผ๋ฏธํฐ๋ก ์ ๋ ฅ๋ ๊ฐ์ด null ์ด๋ผ๋ฉด NPE(NullPointerException)๊ฐ ๋ฐ์ํ๊ณ , ๊ทธ๋ ์ง ์๋ค๋ฉด ์ ๋ ฅ๊ฐ์ ๊ทธ๋๋ก ๋ฐํํ๋ ๊ฐ๋จํ ๋ฉ์์ด์ด๋ค. requireNonNull์ ์๋์ ๊ฐ์ด ์ธ๊ฐ์ง๋ก ์ค๋ฒ๋ก๋ฉ ๋์ด์๋ค.
๋ฆฌํดํ์ | ๋ฉ์๋ |
---|---|
T | requireNonNull(T obj) |
T | requireNonNull(T obj, String message) |
T | requireNonNull(T obj, Supplier msgSupplier) |
์ฒซ๋ฒ์งธ ๋ฉ์๋๋ null์ ์ ๋ฌํ๋ฉด ๋ฉ์ธ์ง๊ฐ ๋น์ด์๋ NPE ์์ธ๋ฅผ ๋์ง๋ค,
Objects.requireNonNull(null);
// java.lang.NullPointerException
๋๋ฒ์จฐ ๋ฉ์๋๋ null์ ์ ๋ฌํ๋ฉด, ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ ๋ฌธ์์ด์ ๋ฉ์ธ์ง๋ก ๊ฐ๋ NPE ์์ธ๋ฅผ ๋์ง๋ค.
Objects.requireNonNull(null, "null์ ์ ๋ฌ๋ ์ ์์ต๋๋ค!");
// java.lang.NullPointerException: null์ ์ ๋ฌ๋ ์ ์์ต๋๋ค!
์ธ๋ฒ์งธ ๋ฉ์๋๋ null์ ์ ๋ฌํ๋ฉด, ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ Supplier๋ฅผ ๊ตฌํํ ์ต๋ช ํจ์์ ๋ฐํ๊ฐ์ ๋ฉ์ธ์ง๋ก ๊ฐ๋ NPE ์์ธ๋ฅผ ๋์ง๋ค.
Objects.requireNonNull(null, () -> "null์ ์ ๋ฌ๋ ์ ์์ต๋๋ค!");
// java.lang.NullPointerException: null์ ์ ๋ฌ๋ ์ ์์ต๋๋ค!
# requireNonNull์ ์ฌ์ฉํ๋ ์ด์
- ๋น ๋ฅธ ์คํจ (Fail-Fast)
๋๋ฒ๊น ์ ์ฝ๊ฒํ๊ธฐ ์ํด์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ฆ๊ฐ์ ์ผ๋ก ๊ฐ์งํ ํ์๊ฐ ์๋ค. ๋ฌธ์ ์ ์์ธ๊ณผ ๋ฌธ์ ์ ๋ฐ์ ์ง์ ์ด ๋ฌผ๋ฆฌ์ ์ผ๋ก ๋จ์ด์ ธ ์๋ค๋ฉด ๋๋ฒ๊น ํ๊ธฐ ์ด๋ ต๋ค. - ๋ช ์์ฑ๊ณผ ๊ฐ๋ ์ฑ