์๋ก
์ฐ์ํ ํ ํฌ์ฝ์ค ํ๋ฆฌ์ฝ์ค ๋ฏธ์ ์ ํ๋ฉด์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋์ค, ํ ์คํธ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ์์ต๋๋ค. (์ต์ข ์ฝ๋๋ ๊ฒ์ฆ ๋ก์ง์ ๋ค๋ฅด๊ฒ ํ๊ธฐ ๋๋ฌธ์ ์ง๊ธ์ ์ด ํ ์คํธ ์ฝ๋๊ฐ ์์ ์์ง ์์ต๋๋ค.)
@Test
@ParameterizedTest
@ValueSource(strings = {"ๅดใฏะปู", "?-bob"})
void ํ๊ธ๊ณผ_์ํ๋ฒณ_์ซ์๋ฅผ_์ ์ธํ_๋ชจ๋ _๋ฌธ์๋_์๋๋ค(final String value) {
// given & when
Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
Name name = Name.from(value);
});
// then
assertThat(exception.getMessage()).isEqualTo(CAR_NAMV_VALUE_EXCEPTION.toString());
}
์ด๋ ๊ฒ ํ๋, ์์์น ๋ชปํ ์์ธ๋ฅผ ๋ฐ๊ฒฌํ ์ ์์์ต๋๋ค.
์ ์ด๋ฐ ์์ธ๊ฐ ๋ฐ์๋ ๊ฒ์ผ๊น์? ์ง๊ธ๋ถํฐ ์์๋ณด๊ฒ ์ต๋๋ค.
1. @Test์ @ParameterizedTest๋ ํจ๊ป ์ฐ๋ฉด ์ ๋๋ค.
์์ ์ฌ์ง์ ๋ณด๋ฉด, ํ๊ธ๊ณผ_์ํ๋ฒณ_์ซ์๋ฅผ_์ ์ธํ_๋ชจ๋ _๋ฌธ์๋_์๋๋ค๊ฐ ๋ ๊ฐ๋ก ์ชผ๊ฐ์ง ๋ค ์ฒซ ๋ฒ์งธ๋ ์คํจ, ๋ ๋ฒ์งธ๋ ์ฑ๊ณตํ์์์ ๋ณผ ์ ์์ต๋๋ค.
์ด๋ @Test์ @ParameterizedTest๋ฅผ ํจ๊ป ์ผ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ ํ์์ ๋๋ค. @Test์ @ParameterizedTest๋ ๊ฐ๊ฐ ํ ๋ฒ ํ ์คํธํ๋์ง, ํ๋ผ๋ฏธํฐ๋ค์ ๋ฃ์ด๋ณด๋ฉฐ ํ ์คํธํ๋์ง์ผ ๋ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ ๋ค์ด๋ฏ๋ก, ์ด๋ค์ ๊ฐ์ด ์ฐ๋ฉด ์ ๋ ๊ฒ ๋ถ๋ฆฌ๊ฐ ๋ฉ๋๋ค.
2. @Test, @ParameterizedTest, @ValueSource ์ฐจ์ด
์ฌ์ฉ๋ ์ด๋ ธํ ์ด์ ๋ค์ ์ฌ์ฉ๋ฒ์ ๋ ์์ธํ ์์๋ณด๊ธฐ ์ํด, ์์ฑ๋ ๋ฌธ์๋ฅผ ์ง์ ๋ฒ์ญํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
@Test
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @API(status = Status.STABLE, since = "5.0") @Testable public @interface Test extends java.lang.annotation.Annotation
@Test๋ ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ ๋ฉ์๋๊ฐ ํ ์คํธ ๋ฉ์๋์์ ๋ํ๋ ๋๋ค. @Test ๋ฉ์๋๋ private์ด๋ static์ด๋ฉด ์ ๋๋ฉฐ, ๊ฐ์ ๋ฐํํด์๋ ์ ๋ฉ๋๋ค. @Test ๋ฉ์๋๋ ParameterResolvers์ ์ํด ํด๊ฒฐ๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ํ์ ์ผ๋ก ์ ์ธํ ์ ์์ต๋๋ค. @Test๋ ๋ํ @Test์ ์๋ฏธ๋ฅผ ์์ํ๋ ์ฌ์ฉ์ ์ ์ ์กฐํฉ ์ด๋ ธํ ์ด์ ์ ๋ง๋ค๊ธฐ ์ํด ๋ฉํ ์ด๋ ธํ ์ด์ ์ผ๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
ํ ์คํธ ์คํ ์์
๊ธฐ๋ณธ์ ์ผ๋ก ํ ์คํธ ๋ฉ์๋๋ ๊ฒฐ์ ์ ์ด์ง๋ง ์ผ๋ถ๋ฌ ๋ช ๋ฐฑํ์ง ์์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ ๋ ฌ๋ฉ๋๋ค. ์ด๋ ํ ์คํธ ์ค์ํธ์ ํ์ ์คํ์์ ํ ์คํธ ๋ฉ์๋๋ฅผ ๋์ผํ ์์๋ก ์คํํ์ฌ ๋ฐ๋ณต ๊ฐ๋ฅํ ๋น๋๋ฅผ ๊ฐ๋ฅ์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์ ํ ์คํธ ๋ฉ์๋๋ ์ง์ ์ ์ผ๋ก @Test, @RepeatedTest, @ParameterizedTest, @TestFactory ๋๋ @TestTemplate์ผ๋ก ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ ์ธ์คํด์ค ๋ฉ์๋์ธ ์ด๋ค ๊ฒ์ด๋ ๋ฉ๋๋ค. ์ง์ ํ ๋จ์ ํ ์คํธ๋ ์ผ๋ฐ์ ์ผ๋ก ์คํ ์์์ ์์กดํด์๋ ์ ๋์ง๋ง, ๋๋ก๋ ๋ช ์์ ์ผ๋ก ํน์ ํ ํ ์คํธ ๋ฉ์๋ ์คํ ์์๋ฅผ ๊ฐ์ ํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. — ์๋ฅผ ๋ค์ด, ์ํ์ค๊ฐ ์ค์ํ ํตํฉ ํ ์คํธ ๋๋ ๊ธฐ๋ฅ ํ ์คํธ๋ฅผ ์์ฑํ ๋, ํนํ @TestInstance(Lifecycle.PER_CLASS)์ ํจ๊ป ์ฌ์ฉ๋ ๋์ ๋๋ค. ํ ์คํธ ๋ฉ์๋์ ์คํ ์์๋ฅผ ์ ์ดํ๋ ค๋ฉด ํ ์คํธ ํด๋์ค ๋๋ ํ ์คํธ ์ธํฐํ์ด์ค์ @TestMethodOrder๋ฅผ ์ด๋ ธํ ์ด์ ์ผ๋ก ๋ฌ๊ณ ์ํ๋ MethodOrderer ๊ตฌํ์ ์ง์ ํ๋ฉด ๋ฉ๋๋ค.
@ParameterizedTest
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @API(status = Status.STABLE, since = "5.7") @TestTemplate @ExtendWith({org.junit.jupiter.params.ParameterizedTestExtension.class}) public @interface ParameterizedTest extends java.lang.annotation.Annotation
@ParameterizedTest๋ ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ ๋ฉ์๋๊ฐ ๋งค๊ฐ๋ณ์ํ๋ ํ ์คํธ ๋ฉ์๋์์ ๋ํ๋ ๋๋ค. ์ด๋ฌํ ๋ฉ์๋๋ private์ด๋ static์ด์ด์๋ ์ ๋ฉ๋๋ค.
์ธ์ ์ ๊ณต ๋ฐ ์์ค
@ParameterizedTest ๋ฉ์๋๋ @ArgumentsSource ๋๋ ํด๋นํ๋ ๊ตฌ์ฑ ์ด๋ ธํ ์ด์ (์: @ValueSource, @CsvSource ๋ฑ)์ ํตํด ์ ์ด๋ ํ๋์ ArgumentsProvider๋ฅผ ์ง์ ํด์ผ ํฉ๋๋ค. ์ด ํ๋ก๋ฐ์ด๋๋ ๋งค๊ฐ๋ณ์ํ๋ ํ ์คํธ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฐ ์ฌ์ฉ๋ Argument์ ์คํธ๋ฆผ์ ์ ๊ณตํ๋ ์ญํ ์ ํฉ๋๋ค.
ํ์ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก
@ParameterizedTest ๋ฉ์๋๋ ๋ฉ์๋์ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก ๋์ ๋ค๋ฅธ ParameterResolver๋ค์ ์ํด ํด๊ฒฐ๋ ์ถ๊ฐ์ ์ธ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์ธํ ์ ์์ต๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก ๋งค๊ฐ๋ณ์ํ๋ ํ ์คํธ ๋ฉ์๋๋ ๋ค์ ๊ท์น์ ๋ฐ๋ผ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์ธํด์ผ ํฉ๋๋ค.
ํ๋ ์ด์์ ์ธ๋ฑ์ฑ๋ ์ธ์๋ ๋จผ์ ์ ์ธ๋์ด์ผ ํฉ๋๋ค. ๊ทธ๋ค์์ ํ๋ ์ด์์ ์ด๊ทธ๋ฆฌ๊ฒ์ดํฐ๊ฐ ์ ์ธ๋์ด์ผ ํฉ๋๋ค. ๋ค๋ฅธ ParameterResolver ๊ตฌํ์์ ์ ๊ณต๋ ํ๋ ์ด์์ ์ธ์๋ ๋ง์ง๋ง์ ์ ์ธ๋์ด์ผ ํฉ๋๋ค.
์ด ๋ฌธ๋งฅ์์ ์ธ๋ฑ์ฑ๋ ์ธ์๋ ArgumentsProvider์ ์ํด ์ ๊ณต๋ Arguments์ ์ฃผ์ด์ง ์ธ๋ฑ์ค์ ๋ํ ์ธ์๋ฅผ ๋ํ๋ด๋ฉฐ, ์ด๋ ๋งค๊ฐ๋ณ์ํ๋ ๋ฉ์๋์ ํ์ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์์ ๋์ผํ ์ธ๋ฑ์ค์ ๋ํ ์ธ์๋ก ์ ๋ฌ๋ฉ๋๋ค. ์ด๊ทธ๋ฆฌ๊ฒ์ดํฐ๋ ArgumentsAccessor ํ์์ ๋งค๊ฐ๋ณ์ ๋๋ @AggregateWith๋ก ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ ๋งค๊ฐ๋ณ์์ ๋๋ค.
์ธ์ ๋ณํ
๋ฉ์๋ ๋งค๊ฐ๋ณ์๋ ๋ช ์์ ArgumentConverter๋ฅผ ์ง์ ํ๊ธฐ ์ํด @ConvertWith ๋๋ ํด๋น ๊ตฌ์ฑ ์ด๋ ธํ ์ด์ ์ผ๋ก ๋ฌ๋ฆด ์ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด JUnit Jupiter๋ ๋์ ํ์์ผ๋ก์ ์์์ ๋ณํ์ ์๋์ผ๋ก ์๋ํ ๊ฒ์ ๋๋ค(์์ธํ ๋ด์ฉ์ ์ฌ์ฉ์ ๊ฐ์ด๋๋ฅผ ์ฐธ์กฐํ์ธ์).
์กฐํฉ๋ ์ด๋ ธํ ์ด์
@ParameterizedTest๋ @ParameterizedTest์ ์๋ฏธ๋ฅผ ์์ํ๋ ์ฌ์ฉ์ ์ ์ ์กฐํฉ ์ด๋ ธํ ์ด์ ์ ๋ง๋ค๊ธฐ ์ํด ๋ฉํ ์ด๋ ธํ ์ด์ ์ผ๋ก๋ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
ํ ์คํธ ์คํ ์์
๊ธฐ๋ณธ์ ์ผ๋ก ํ ์คํธ ๋ฉ์๋๋ ๊ฒฐ์ ์ ์ด์ง๋ง ์ผ๋ถ๋ฌ ๋ช ๋ฐฑํ์ง ์์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ ๋ ฌ๋ฉ๋๋ค. ์ด๋ ํ ์คํธ ์ค์ํธ์ ํ์ ์คํ์์ ํ ์คํธ ๋ฉ์๋๋ฅผ ๋์ผํ ์์๋ก ์คํํ์ฌ ๋ฐ๋ณต ๊ฐ๋ฅํ ๋น๋๋ฅผ ๊ฐ๋ฅ์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์ ํ ์คํธ ๋ฉ์๋๋ ์ง์ ์ ์ผ๋ก @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, ๋๋ @TestTemplate์ผ๋ก ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ ์ธ์คํด์ค ๋ฉ์๋์ธ ์ด๋ค ๊ฒ์ด๋ ๋ฉ๋๋ค. ์ง์ ํ ๋จ์ ํ ์คํธ๋ ์ผ๋ฐ์ ์ผ๋ก ์คํ๋๋ ์์์ ์์กดํด์๋ ์ ๋์ง๋ง, @TestMethodOrder๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ๋ฉ์๋์ ์คํ ์์๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค. ํนํ @TestInstance(Lifecycle.PER_CLASS)์ ํจ๊ป ์ฌ์ฉ๋๋ ํตํฉ ํ ์คํธ๋ ๊ธฐ๋ฅ ํ ์คํธ๋ฅผ ์์ฑํ ๋ ํ ์คํธ์ ์์๊ฐ ์ค์ํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ํ ์คํธ ๋ฉ์๋์ ์คํ ์์๋ฅผ ์ ์ดํ๋ ค๋ฉด ํ ์คํธ ํด๋์ค ๋๋ ํ ์คํธ ์ธํฐํ์ด์ค์ @TestMethodOrder๋ฅผ ์ด๋ ธํ ์ด์ ์ผ๋ก ๋ฌ๊ณ ์ํ๋ MethodOrderer ๊ตฌํ์ ์ง์ ํ๋ฉด ๋ฉ๋๋ค.
@ValueSource
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @API(status = Status.STABLE, since = "5.7") @ArgumentsSource(org.junit.jupiter.params.provider.ValueArgumentsProvider.class) public @interface ValueSource extends java.lang.annotation.Annotation
@ValueSource๋ ๋ฆฌํฐ๋ด ๊ฐ์ ๋ฐฐ์ด์ ์ก์ธ์ค ํ๋ ArgumentsSource์ ๋๋ค. ์ง์๋๋ ์ ํ์ short, byte, int, long, float, double, char, boolean, String ๋ฐ Class๋ฅผ ํฌํจํฉ๋๋ค. ๊ทธ๋ฌ๋ @ValueSource ์ ์ธ๋น ํ๋์ ์ง์๋๋ ์ ํ๋ง ์ง์ ํ ์ ์์ต๋๋ค. ์ ๊ณต๋ ๋ฆฌํฐ๋ด ๊ฐ์ ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ @ParameterizedTest ๋ฉ์๋์ ์ธ์๋ก ์ ๊ณต๋ฉ๋๋ค.
๋ค์ ์ค๋ช ์ด ๊ธธ์ง๋ง, ํต์ฌ์ ์ ๋ฆฌํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค๊ณ ํ ์ ์์ต๋๋ค.
- @Test ๋ฉ์๋๋ ParameterResolver์ ์ํด ํด๊ฒฐ๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ํ์ ์ผ๋ก ์ ์ธํ ์ ์์ต๋๋ค.
- @ParameterizedTest๋ฅผ ์ฌ์ฉํ ๋๋ @ValueSource, @CsvSource ๋ฑ์ ํตํด ์ ์ด๋ ํ๋์ ArgumentsProvider๋ฅผ ์ง์ ํด์ผ ํฉ๋๋ค.
- @ValueSource๋ @Parameterized์ ์ธ์๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
3. ํ ์คํธ ์ฝ๋์ ๋ด๋ถ์ ํ๋ฆ
์ด์ ํต์ฌ์ผ๋ก ๋ค์ด๊ฐ๋ณด๊ฒ ์ต๋๋ค! ๋ด์ฅ๋ ํ ์คํธ ์ฝ๋๋ฅผ ๋ถ์ํด ๋ณด๋ฉด, ParameterResolver์ ๊ตฌํ์ฒด๋ค์์ supportsParameter๊ฐ ํธ์ถ๋ฉ๋๋ค. ์ด๋ ์์ ์๋ ParameterResolver์ ์ํด ํด๊ฒฐ๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ํ์ ์ผ๋ก ์ ์ธํ ์ ์์ต๋๋ค.์ ์ํด ์คํ๋ฉ๋๋ค.
์ด๊ฒ์ ์คํํ ์ ์๋๋ก ํ๋ ๊ฒ์ ExecutableInvoker ๋๋ถ์ ๋๋ค.
ExecutableInvoker
ExecutableInvoker๊ฐ resolveParameters ๋ฉ์๋๋ก ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ๊ฐ์ ํ๋ผ๋ฏธํฐ๋ง๋ค ์ง์๋๋ ๋ฆฌ์กธ๋ฒ๊ฐ ์๋์ง resolveParameter๋ฅผ ํธ์ถํจ์ ํ์ธํ ์ ์์ต๋๋ค.
resolveParameter๋ ๋น์์ ธ ์์ ์ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ํ ์ง์๋๋ ํ๋ผ๋ฏธํฐ ๋ฆฌ์กธ๋ฒ๊ฐ ๋ ๊ฐ ์ด์์ผ ๊ฒฝ์ฐ์๋ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
๋ค์ ํ๋ฆ์ ๋ณด๊ฒ ์ต๋๋ค!
ParameterContext, Executable executable, ExtensionContext, ExtensionRegistry ๋ฑ์ด ๋ณด์ ๋๋ค. ๋๋ฒ๊น ์ ํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋ค์ด ์ ์ฅ๋์ด ์์ต๋๋ค.
์ฆ, extensionRegistry์์ stream ๋ฉ์๋๋ฅผ ์คํํ ๋ค matchingResolvers์ ์ฌ์ด์ฆ๊ฐ ๋น์ด์์ผ๋ฉด ์ฐ๋ฆฌ๊ฐ ์ ํ๋ ์์ธ๊ฐ ๋ฐ์ํ๋ค๋ ๋ป์ ๋๋ค.
resolveParameter ํจ์์์ ์ง์ ๋ extensionRegistry์ ๊ฐ์ผ๋ก MutableExtensionRegistry๊ฐ ๋ค์ด์์์ ํ์ธํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ์ด์ MutableExtensionRegistry๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
MutableExtensionRegistry
์ฝ๋๋ฅผ ๋ฏ์ด๋ณด๋ฉด, ExtensionRegistry์ ๊ตฌํ์ฒด๋ก๋ MutableExtensionRegistry๋ง ์์์ ์ ์ ์์ต๋๋ค.
์๋๋ ExtensionRegistry์ ์ ์๋ stream ๋ฉ์๋์ ์ฉ๋ฒ์ ๋๋ค.
Extension์ ์์๋ฐ์ ํด๋์ค๋ค ์ค, extensionType์ ํด๋น๋๋ ๊ฒ๋ค์ ์คํธ๋ฆผ์ผ๋ก ๊ฐ์ ธ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์๊น ์์์ ๋ณด๋ฉด, extensionType์ด ParameterResolver์์ต๋๋ค.
๋ฐ๋ผ์ ParameterResolver์ ๊ตฌํ์ฒด (ParameterResolver ์์ฒด๊ฐ Extension์ ์์๋ฐ์ต๋๋ค.)๋ค์ ๊ฐ์ ธ์ต๋๋ค.
์ด ๊ตฌํ์ฒด๋ค์๊ฒ ์ ๋ถ supportsParameter(parameterContext, extensionContext)๋ฅผ ๋ฌผ์ด๋ด ๋๋ค. ๊ทธ๋ฆฌ๊ณ true๋ก ์๋ตํ๋ ๊ตฌํ์ฒด๋ค์ ๋ฆฌ์คํธ๋ก ์ทจํฉํ ๋ค ๋น์ด ์๋ค๋ฉด ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
4. ๊ฐ ParameterResolver ๊ตฌํ์ฒด์ supportsParameter ํ์ ๋ฐฉ์ ์์๋ณด๊ธฐ
๋ํ์ ์ผ๋ก TempDirectory, TestInfoParameterResolver, TestReporterParameterResolver, ParameterizedTestParameterResolver์ ์๋ฆฌ๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค.
TempDirectory
TempDirectory์ ๋ด๋ถ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
// Determine if the Parameter in the supplied ParameterContext is annotated with @TempDir.
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
boolean annotated = parameterContext.isAnnotated(TempDir.class);
if (annotated && parameterContext.getDeclaringExecutable() instanceof Constructor) {
throw new ParameterResolutionException(
"@TempDir is not supported on constructor parameters. Please use field injection instead.");
}
return annotated;
}
์ฐ๋ฆฌ๋ void ํ๊ธ๊ณผ_์ํ๋ฒณ_์ซ์๋ฅผ_์ ์ธํ_๋ชจ๋ _๋ฌธ์๋_์๋๋ค(final String value)์ ๊ฐ์ด ํ๋ผ๋ฏธํฐ์ ๋จ์ String์ ๋ฃ์์์ต๋๋ค. @TempDir์ด ๋ฌ๋ ค์์ง ์๊ธฐ์, ์์ supportsParameter์์๋ false๊ฐ ๋ฐํ๋ฉ๋๋ค.
์ฌ๋ด์ผ๋ก, TempDir์ ์๋์ฒ๋ผ ์ธ์์ ๋ฃ์ ์๋ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ getDeclaringExecutable์ ๋ณด๋ฉด ๋ฉ์๋์ธ์ง ์์ฑ์์ธ์ง๋ฅผ ๊ตฌ๋ณํ๋ ๋ฐ ์ฌ์ฉ๋จ์ ์ ์ ์์ต๋๋ค.
TestInfoParameterResolver
TestInfoParameterResolver๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
parameterContext.getParameter๋ Parameter๋ฅผ ๊ฐ์ ธ์ค๋ฉฐ, ์ด๊ฒ์ getType ๋ฉ์๋๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
tmp์ String์ด ๋ค์ด๊ฐ ๊ฒ์ด ๋ณด์ด์๋์? ์ด๋ ์ฐ๋ฆฌ๊ฐ ์ธ์์ String์ ๋ฃ์ด๋จ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ฆ, String์ TestInfo.class๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ์ด ๋ํ false๊ฐ ๋ฉ๋๋ค.
TestReporterParameterResolver
TestReporterParameterResolver๊ฐ ์ ๋๋ ์ด์ ๋ ๋น์ทํฉ๋๋ค. TestReporter.class๊ฐ ์๋๊ธฐ ๋๋ฌธ์ false๋ก ๋ฉ๋๋ค.
ParameterizedTestParameterResolver, RepetitionInfoParameterResolver, SoftAssertionsExtension, TypeBasedParameterResolver์ ๋๋ฒ๊ทธ ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ๊ฑธ์ด๋ ํธ์ถ๋์ง ์์์ต๋๋ค. ์๋ง @Test์ผ ๋๋ ํธ์ถ๋์ง ์๋ ๊ฒ ๊ฐ์๋ฐ, ์ด ๋ถ๋ถ์ ๋ ์์๋ด์ผ ํ ๋ฏํฉ๋๋ค.
์ง๊ธ๊น์ง @Test๋ฅผ ๋ถ์ธ ๋ค ์ธ์์ String ๋ฑ ์ผ๋ฐ์ ์ธ ํ์ ์ ์์ฑํด ๋๋ฉด matchingResolvers๊ฐ ๋น์์ง ์ํ๋ผ ์์ธ๊ฐ ๋ฐ์ํ ๊ฒ์์ ์ ์ ์์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ง์ง๋ง์ผ๋ก ParameterizedTestParameterResolver๋ ์ด๋ค์ง ๋ณด๊ฒ ์ต๋๋ค.
ParameterizedTestParameterResolver
declaringExecutable, testMethod, parameterIndex๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ฅ๋ฉ๋๋ค.
๋ณด๋ ๋ฐ์ ๊ฐ์ด, declaringExecutable๊ณผ testMethod๊ฐ ๊ฐ์ผ๋ฏ๋ก ํต๊ณผ๋๋ฉฐ, ๊ทธ ์ดํ์ ์กฐ๊ฑด๋ค๋ ๋ฌธ์ ์์ด ํต๊ณผ๋ฉ๋๋ค. (Aggrregator์ ๋ํด์๋ @ParameterizedTest์ ์ค๋ช ์ ๊ธฐ๋ก๋์ด ์๊ธด ํ์ง๋ง, ์ ํํ ๋ฌด์์ธ์ง ๋ ์์๋ด์ผ ํ ๋ฏํฉ๋๋ค. ๊ด๋ จ ํด๋์ค๋ ParameterizedTestMethodContext์ ๋๋ค.)
@ParameterizedTest๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ์์ ๊ฒฝ์ฐ, ๋ง์ง๋ง์ return ๋ฌธ์ ๋๋ฌํ์ฌ true๋ฅผ ๋ฐํํฉ๋๋ค.
๊ฒฐ๋ก
๊ฐ์ธ์ ์ธ ์ถ์ธก์ด์์ง๋ง, ์ง๊ธ๊น์ง์ ์๋๋ก ๋ฏธ๋ฃจ์ด๋ดค์ ๋๋ ํ ์คํธ ์ฝ๋ ์คํ ์ ์์ฑ๋ ๊ฐ๊ฐ์ ํ๋ผ๋ฏธํฐ์ ์ข ๋ฅ์ ๋ฐ๋ผ ์ง์ ๊ฐ๋ฅํ ParameterResolver๋ค์ด ๋์ค๊ณ , ์์ ๊ฐ๋ฅํ ๊ฒ ์๋ค๋ฉด ์์ธ๊ฐ ํฐ์ง๋ค๋ ์ ์ ์์๋์ต๋๋ค.
supportsParameter์ ์ธ์์์ ParameterContext (ํ๋ผ๋ฏธํฐ ์ ๋ณด)์ ExtensionContext (ํ ์คํธ ์คํ ์ค ์ฌ์ฉ ๊ฐ๋ฅํ ํ์ฅ ์ฝํ ์คํธ ์ ๋ณด)๊ฐ ์ฐ์ธ๋ค๋ ์ ์์, ๊ฐ์ข ์กฐํฉ์ ๋ฐ๋ฅธ ๋ต์ด ์๋ ๋ฏํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , @Test์ @ParameterizedTest์์ ๋ฐ๋ผ์ String ์ธ์๋ฅผ ๋ถ์ฌ๋ ๋๊ณ , ๋ถ์ด์ง ์์๋ ๋๋ ๊ฒ ๋๋๊ธฐ ๋๋ฌธ์ ์์ฐ์ค๋ฝ๊ฒ @Test์ @ParameterizedTest๋ฅผ ํผ์ฉํ๋ฉด ์ ๋๋ค๋ ์ ๋ ์๊ฒ ๋์์ต๋๋ค. (@Test์ผ ๋๋ String ์ธ์๋ฅผ ๋ถ์ด๋ฉด ์ ๋์ง๋ง, @ParameterizedTest์์๋ ๋ถ์ฌ๋ ๋์ฃ !)
์คํธ๋ฆผ๊ณผ ์ ๋ค๋ฆญ, Aggregator ๋ฑ ์์ง๋ ๋ฐฐ์ธ ๊ฒ ๋ง๋ค๋ ๊ฒ์ ์์ผ ๋๊ผ๊ณ , ์๊ฒ๋๋ง JUnit5์ ์ด๋ฌํ ๋ด๋ถ ์๋ฆฌ๋ฅผ ํ์ ํ๊ฒ ๋ ๊ฒ ๊ฐ์ ์ ์ตํ ๊ฒฝํ์ด์์ต๋๋ค.
์ค๋ฅ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ธฐ๋กํ๋ค ๋ณด๋ ํ๋ฆฐ ์ ๋ณด๋ค์ด ์์ ์ ์์ต๋๋ค. ๊ณ ์น ์ ์ด ์๋ค๋ฉด ๋ฐ๋ก ์์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค!