@ValueSource(), @CsvSource() ๋ฅผ ํตํด ๊ธฐ๋ณธ ints, strings ๋ฑ ๋ค์ํ ์๋ฐ์ ํ์ ์ ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ๋๊ฒจ์ฃผ๊ณ , ์ฌ๋ฌ๊ฐ์ ์ธ์๋ฅผ csvํ์์ผ๋ก ๋๊ฒจ์ค ์ ์์๋ค!
๊ทธ๋ฐ๋ฐ ์ข ๋ โ๋ณต์กํโ ๋ ์๋ค์ ๋๊ฒจ์ฃผ๊ณ ์ถ๋ค๋ฉด? ๐คจ
์๋ฅผ ๋ค์ด List ๊ฐ์ฒด, ๋๋ ์ฌ์ฉ์ ์ ์ ๊ฐ์ฒด ๊ฐ์ ๋ ์๋ค ๋ง์ด๋ค!
*@MethodSouce : ํ๋ผ๋ฏธํฐ๋ฅผ ์ ์ํ๊ณ , ๋ฐํํด์ฃผ๋ method๋ฅผ ์ ์ํ์. ๊ทธ๋ฆฌ๊ณ Stream์ ๋ฐํ๋ฐ์! (static)*
์ฌ์ฉ ์์์ ํจ๊ป ๋ณด๋ฉด ๋ ๋น ๋ฅด๊ฒ ์ดํดํ ์ ์๋ค.
@ParameterizedTest
@MethodSource("generateTestLottoInput")
void ๋ก๋๋ฒํธ๋ฅผ_๋ฐ๋๋ค(List<Integer> input) {
System.out.println(input);
}
static Stream<List<Integer>> **generateTestLottoInput**() {
return Stream.of(
List.of(8, 21, 23, 41, 42, 43),
List.of(3, 5, 11, 16, 32, 38),
List.of(7, 11, 16, 35, 36, 44)
);
}
@MethodSource("generateTestLottoInput")
๋ generateTestLottoInput()
๋ฅผ ํธ์ถํด ์ธ์๋ฅผ ๋ฐ์์ฌ ๊ฒ์์ ๋ช
์ํ๊ณ ์๋ค.
generateTestLottoInput()
๋ List<Integer>
๋ก ๊ตฌ์ฑ๋ Stream
์ ๋ฐํํ๋ค!
๊ทธ๋ฆฌ๊ณ Stream
, List
์ ๊ฐ์ ๊ฐ์ฒด๋ of() (static)
ํจ์๋ฅผ ํตํด ์์ฑ ๊ฐ๋ฅํ๋ค.
๋น์ฐํ ๊ทธ๋ด ํ์ ์์ด, ์ฌ๋ฌ๊ฐ์ ์ธ์๋ฅผ ๋ฐ๊ณ ์ถ์๋๋ Arguments
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค.
Arguments
๋ฅผ ์ฌ์ฉํด ์ฌ๋ฌ๊ฐ์ ์ธ์๋ฅผ ํ๋ฒ์ ๋ฌถ๊ณ , ์ด๋ฅผ Stream์ผ๋ก ๊ตฌ์ฑํด ๋ฐํํ์!
@ParameterizedTest
@MethodSource("generateTestLottoInput")
void ๋ก๋์_๊ตฌ์
๊ธ์ก_์ธ์๋ก๋ฐ๊ธฐ(List<Integer> input, int money) {
System.out.println(input);
System.out.println(money);
}
static Stream<Arguments> **generateTestLottoInput**() {
return Stream.of(
Arguments.arguments(List.of(7, 11, 16, 35, 36, 44), 8000),
Arguments.arguments(List.of(3, 5, 11, 16, 32, 38), 1000),
);
}
@Test
void ๊ธฐ๋ฅ_ํ
์คํธ() {
assertRandomUniqueNumbersInRangeTest(
() -> {
run("8000", "1,2,3,4,5,6", "7");
assertThat(output()).contains(
"8๊ฐ๋ฅผ ๊ตฌ๋งคํ์ต๋๋ค.",
"[8, 21, 23, 41, 42, 43]",
"[3, 5, 11, 16, 32, 38]",
"[7, 11, 16, 35, 36, 44]",
"[1, 8, 11, 31, 41, 42]",
"[13, 14, 16, 38, 42, 45]",
"[7, 11, 30, 40, 42, 43]",
"[2, 13, 22, 32, 38, 45]",
"[1, 3, 5, 14, 22, 45]",
"3๊ฐ ์ผ์น (5,000์) - 1๊ฐ",
"4๊ฐ ์ผ์น (50,000์) - 0๊ฐ",
"5๊ฐ ์ผ์น (1,500,000์) - 0๊ฐ",
"5๊ฐ ์ผ์น, ๋ณด๋์ค ๋ณผ ์ผ์น (30,000,000์) - 0๊ฐ",
"6๊ฐ ์ผ์น (2,000,000,000์) - 0๊ฐ",
"์ด ์์ต๋ฅ ์ 62.5%์
๋๋ค."
);
},
List.of(8, 21, 23, 41, 42, 43),
List.of(3, 5, 11, 16, 32, 38),
List.of(7, 11, 16, 35, 36, 44),
List.of(1, 8, 11, 31, 41, 42),
List.of(13, 14, 16, 38, 42, 45),
List.of(7, 11, 30, 40, 42, 43),
List.of(2, 13, 22, 32, 38, 45),
List.of(1, 3, 5, 14, 22, 45)
);
}
์ ์ฝ๋๋ ๋ก๋ ๊ฒ์์ ์์ ๋ถํฐ ์ข ๋ฃ๋ฅผ ์ถ๋ ฅํ๋ ์ฝ๋์ด๋ค.
"8000"์ ์ ๋ ฅํ๋ค.
๋ก๋๋๋ฒ, ๋ณด๋์ค ๋๋ฒ๋ฅผ ์ ๋ ฅํ๋ค."1,2,3,4,5,6", "7"
์์คํ ์์๋
List.of(8, 21, 23, 41, 42, 43),
List.of(3, 5, 11, 16, 32, 38),
List.of(7, 11, 16, 35, 36, 44),
List.of(1, 8, 11, 31, 41, 42),
List.of(13, 14, 16, 38, 42, 45),
List.of(7, 11, 30, 40, 42, 43),
List.of(2, 13, 22, 32, 38, 45),
List.of(1, 3, 5, 14, 22, 45)
8๊ฐ์ ๋ก๋๋ฅผ ๋ฐํํ๋ค.
public abstract class NsTest {
private PrintStream standardOut;
private OutputStream captor;
@BeforeEach
protected final void init() {
standardOut = System.out;
captor = new ByteArrayOutputStream();// ๊ธฐ์กด Sytem.out์ ์คํธ๋ฆผ ์ ์ฅ
System.setOut(new PrintStream(captor));// System.out์ผ๋ก ์ถ๋ ฅํ๋ ์คํธ๋ฆผ์ captor๋ก ๋ณ๊ฒฝ
}
@AfterEach
protected final void printOutput() {
System.setOut(standardOut); // ๊ธฐ์กด Sytem.out์คํธ๋ฆผ์ผ๋ก ์ถ๋ ฅ ์คํธ๋ฆผ ๋ณ๊ฒฝ
System.out.println(output());
}
protected final String output() {
return captor.toString().trim();
}
protected final void run(final String... args) {
try {
command(args);
runMain();
} finally {
Console.close();
}
}
protected final void runException(final String... args) {
try {
run(args);
} catch (final NoSuchElementException ignore) {
}
}
private void command(final String... args) {
final byte[] buf = String.join("\n", args).getBytes();
System.setIn(new ByteArrayInputStream(buf));
}
protected abstract void runMain();
}
NsTest๋ ํ ์คํธ ์ดํ๋ฆฌ์ผ์ด์ ์์ ์ฝ์์์ ์ ๋ ฅ๋ฐ๊ฑฐ๋ ์ถ๋ ฅํ๋ ๊ฐ๋ค์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด System.setOut๊ณผ System.setIn์ ์ฌ์ฉํ๋ค. ๋จผ์ ์ฝ์ ์ถ๋ ฅ๊ฐ(System.out.println)์ ๋ด๋ถ ๋ณ์์ ์ด๋ป๊ฒ ๋ด๋์ง ์์๋ณด์.
NsTest๋ BeforeEach์ AfterEach ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด Test ์ค์ System.out.println ๋ฉ์๋๋ก ์ฝ์์ ์ถ๋ ฅํ๋ ๊ฐ์ captor์ ๋ด์๋๋ค.
์ฝ์์์ ์ ๋ ฅํด์ผ ํ๋ ๊ฐ์ ๋ฏธ๋ฆฌ command ๋ฉ์๋์ String ๊ฐ(String... args)์ผ๋ก ์ ๋ฌํ๋ค. ์ ๋ฌํ String ๊ฐ์ byte ๋ฐฐ์ด์ธ buf ๋ณ์์ ๋ด๋๋ค. ๊ทธ๋ฆฌ๊ณ buf ๊ฐ์ ByteArrayInputStream ํํ๋ก System.in ์ ๋ ฅ ์คํธ๋ฆผ์ผ๋ก ์ฌ์ฉํ๋ค. ์ฆ, Scanner.nextLine ๋ฑ์ ํธ์ถํด ์ฝ์์์ ์ ๋ ฅ๊ฐ์ ๋ฐ์ ๋ ์ค์ ๋ก ์ฝ์์์ ์ ๋ ฅํ๋ ๊ฒ ์๋๋ผ buf ๋ฐฐ์ด ์์ ๊ฐ๋ค์ ์ฐจ๋ก๋ก ์ ๋ฌํ๋ ๊ฒ์ด๋ค.
ApplicationTest์์ ์ฌ์ฉํ๋ run๋ฉ์๋๋ command๋ฉ์๋์ runMain๋ฉ์๋๋ก ๊ตฌ์ฑ๋๋ค. command ๋ฉ์๋๋ ๊ฒ์ ์ ์ ๊ฐ ์ ๋ ฅํด์ผ ํ๋ ์ฌ๋ ค๋ ๊ฐ(8000), ๋ก๋ ๋น์ฒจ ๋ฒํธ(1,2,3,4,5,6), ๋ณด๋์ค ๋ฒํธ(7) ์ ๋ฐ๋๋ค. ์์์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ command๋ ์ ๋ฌ๋ฐ์ ๋ฌธ์์ด์ System.in์ ์ ๋ ฅ ์คํธ๋ฆผ์ผ๋ก ๋๊ธฐ์ํจ๋ค. runMain๋ฉ์๋๋ ApplicationTest์์ ์ค๋ฒ๋ผ์ด๋ฉํ ๋ฉ์๋๋ก ํ ์คํธ ํด๋์ค Application์ ์คํํ๋ค. Application์ ์คํํ๋ฉด์ Scanner.nextLine()์ ํธ์ถํ ๋๋ง๋ค command์ ์ ๋ฌํ ๋ฌธ์์ด ๊ฐ์ ๋ฆฌํด๋ฐ๋ ๊ฒ์ด๋ค.
public static void assertRandomUniqueNumbersInRangeTest(
final Executable executable,
final List<Integer> value,
final List<Integer>... values
) {
assertRandomTest(
() -> Randoms.**pickUniqueNumbersInRange**(anyInt(), anyInt(), anyInt()),
executable,
value,
values
);
assertRandomUniqueNumbersInRangeTest ๋ฉ์๋๋ Executable, value, values๋ฅผ ์ ๋ฌ๋ฐ๋๋ค. ์ด๊ฒ์ ๊ทธ๋๋ก "() -> Ra*ndoms.pickUniqueNumbersInRange(anyInt(), anyInt(), anyInt())"์ ํจ๊ป assertRandomTest ๋ฉ์๋์ ์ ๋ฌํ๋ค. assertRandomTest๋ ํ๋ง๋๋ก verification์ด ํธ์ถ๋๋ค๋ฉด value, values๋ฅผ* ๋ฌถ์ ์ด๋ ์ด์ ๊ฐ๋ค์ ์ฐจ๋ก๋ก ๋ฆฌํดํด, Executable์ ์คํํ๋ ๊ฒ์ด๋ค.
private static <T> void assertRandomTest(
final Verification verification,
final Executable executable,
final T value,
final T... values
) {
assertTimeoutPreemptively(RANDOM_TEST_TIMEOUT, () -> {
try (final MockedStatic<Randoms> mock = mockStatic(Randoms.class)) {
mock.when(verification).thenReturn(value, Arrays.stream(values).toArray());
executable.execute();
}
});
}