๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring/Test

@TempDir ํ™œ์šฉํ•ด์„œ ํŒŒ์ผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

by ํ‘์‹œ๋ฐ” 2023. 9. 25.

๐Ÿค” ๋ฐฐ๊ฒฝ

์™ธ๋ถ€ ์„œ๋น„์Šค์—์„œ ๋งค์ผ ํŠน์ • ์‹œ๊ฐ„์— ๋ฐฐ์น˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋˜๋Š” csv ํŒŒ์ผ์„ ์ฝ๋Š” ๋ฐฐ์น˜ ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•œ ๋’ค, ํŒŒ์ผ ์ฝ๋Š” ๋ถ€๋ถ„์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ..

 

ํŒŒ์ผ ๊ด€๋ จ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์ฒ˜์Œ์ด๋ผ "ํŒŒ์ผ์€ ์–ด๋–ป๊ฒŒ ๋ฐ˜๋ณต์ ์ธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ๋ ๊นŒ?"๋ผ๋Š” ๊ณ ๋ฏผ์„ ํ•˜๊ฒŒ ๋˜์—ˆ๊ณ , ๊ด€๋ จ ๋‚ด์šฉ์„ ์ฐพ์•„๋ณด๋ฉฐ ์•Œ๊ฒŒ ๋œ  @TempDir์ด๋ผ๋Š” ๊ฑธ ํ™œ์šฉํ•ด ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค.

 

ํ•ด๋‹น ๊ฒฝํ—˜์„ ๋ฐ”ํƒ•์œผ๋กœ @TempDir์„ ํ†ตํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฒ•์— ๋Œ€ํ•ด ๊ณต์œ ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

1. @TempDir ์ด๋ž€

- Junit์—์„œ ์ง€์›ํ•˜๋Š” ์ž„์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ƒ์„ฑ์šฉ ํ…Œ์ŠคํŠธ ์–ด๋…ธํ…Œ์ด์…˜

- ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ ๋˜๋Š” ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์˜ ๋ชจ๋“  ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด ์ž„์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

- ํ…Œ์ŠคํŠธํ•  ๋•Œ ์ง์ ‘ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์‚ญ์ œํ•˜๋Š” ๊ณผ์ •์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ œ๊ฑฐํ•ด ์ค€๋‹ค.

2. ์ฃผ์˜์‚ฌํ•ญ

@TempDir์€ ๋‘ ๊ฐ€์ง€ ํƒ€์ž…๋งŒ ์ง€์›ํ•œ๋‹ค.

 

(1) java.nio.file.Path

(2) java.io.File

 

๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ParameterResolutionException ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

3. ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

public class TempFileTest {

    @Getter
    @Builder
    public static class CsvFile {

        private int id;
        private String name;
        private String type;
    }

    @Test
    @DisplayName("1. Path ํ˜•์‹์œผ๋กœ ์ฝ๊ธฐ")
    void simpleTestTempDirByPath(@TempDir Path tempDir) throws IOException {
        // given
        Path fileDir = tempDir.resolve("test.csv");
        List<String> lines = List.of("1,ํ‘์‹œ๋ฐ”,๋ธ”๋กœ๊ทธ", "2,๋ฐฑ์‹œ๋ฐ”,์นดํŽ˜");
        Files.write(fileDir, lines);

        // when
        List<CsvFile> records = readCsvFile(fileDir.toFile());

        // then
        assertThat(records).hasSize(2)
                .extracting("id", "name", "type")
                .contains(tuple(1, "ํ‘์‹œ๋ฐ”", "๋ธ”๋กœ๊ทธ"), tuple(2, "๋ฐฑ์‹œ๋ฐ”", "์นดํŽ˜"));
    }

    @TempDir File tempFile;

    @Test
    @DisplayName("2. File ํ˜•์‹์œผ๋กœ ์ฝ๊ธฐ")
    void simpleTestTempDirByFile() throws IOException {
        // given
        File testFile = new File(tempFile, "simpleTest.txt");
        List<String> lines = List.of("1,ํ‘์‹œ๋ฐ”,๋ธ”๋กœ๊ทธ", "2,๋ฐฑ์‹œ๋ฐ”,์นดํŽ˜");
        Files.write(testFile.toPath(), lines);

        // when
        List<CsvFile> records = readCsvFile(testFile);
        // then
        assertThat(records).hasSize(2)
                .extracting("id", "name", "type")
                .contains(tuple(1, "ํ‘์‹œ๋ฐ”", "๋ธ”๋กœ๊ทธ"), tuple(2, "๋ฐฑ์‹œ๋ฐ”", "์นดํŽ˜"));
    }

    private List<CsvFile> readCsvFile(File fileDir) throws IOException {
        List<CsvFile> records = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(fileDir))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                records.add(CsvFile.builder()
                        .id(Integer.parseInt(values[0]))
                        .name(values[1])
                        .type(values[2])
                        .build());
            }
        }
        return records;
    }
}

์œ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์˜ˆ์‹œ์ฒ˜๋Ÿผ Path ๋˜๋Š” File์— @TempDir ์ฃผ์„๊ณผ ํ•จ๊ป˜ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

ํŒŒ๋ผ๋ฏธํ„ฐ ๋˜๋Š” ํ•„๋“œ ํ˜•์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ž‘์„ฑ์ž ์ž์œ ์ด๋‹ค.

 

- ๋งŒ์•ฝ ํ…Œ์ŠคํŠธ๋ผ๋ฆฌ ํŒŒ์ผ/๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด,

 

ํ•„๋“œ ๋ฐฉ์‹ + static์„ ์„ ์–ธํ•ด์„œ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค. ๋‹จ, ํ…Œ์ŠคํŠธ๋Š” ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋งŒ์•ฝ ์—ฐ์†์„ฑ ์žˆ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ @Order์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆœ์„œ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€์‹œํ‚ค๋Š” ๊ฒŒ ์ค‘์š”ํ•˜๋‹ค.

 

- JUnit 5.9 ๋ฒ„์ „๋ถ€ํ„ฐ @TempDir์—๋Š” cleanup์ด๋ผ๋Š” ์˜ต์…˜์„ ์ œ๊ณตํ•œ๋‹ค.

 

ํ•ด๋‹น ์˜ต์…˜์€ 3๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ALWAYS: ํ…Œ์ŠคํŠธ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„, ์ž„์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ •๋ฆฌ (๊ธฐ๋ณธ ์„ค์ •)
NEVER: ํ…Œ์ŠคํŠธ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„, ์ž„์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ •๋ฆฌ X
ON_SUCCESS : ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ์—๋งŒ ์ž„์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ •๋ฆฌ

 

๋งŒ์•ฝ ์ž„์‹œ๋กœ ์ƒ์„ฑํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ, ํŒŒ์ผ์„ ์œ ์ง€ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด REFERENCE๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์ž.

REFERENCE

https://www.baeldung.com/junit-5-temporary-directory

 

๋Œ“๊ธ€