자바 표준 입출력 리다이렉션

V_브이_v·2024년 11월 28일
3

자바스터디

목록 보기
3/4
post-thumbnail

표준 입출력 리다이렉션

테스트 코드를 진행하기 위해서는 자바 표준 입출력의 리다이렉션을 공부해야합니다

자바 표준 입출력이란?
System.in, System.out 같은 것을 말하는겁니다


아래에 제가 준비한 실습코드를 직접 타자치면서
어떻게 동작하는지 배워보시면 이해가 빠르게 될 겁니다


실습 코드 1: 출력 스트림 테스트

모니터에 출력되는 내용을 문자열로 받을 수 있도록 테스트 코드를 작성해봤습니다.
이 코드는 실제 출력을 변경하지 않고 별도의 문자열에 저장합니다.

private static void lab4() {

        System.out.println("--시작4--");
        // ByteArrayOutputStream을 생성하여 출력 내용을 메모리 내에서 저장할 수 있게 합니다.
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        // System.out을 output이라는 PrintStream으로 set한다.
        System.setOut(new PrintStream(output));

        // .println() 호출 시 실제 콘솔이 아닌 output에 문자열이 저장됨
        System.out.println("안녕하세요");
        System.out.println("반갑습니다");

        // System.out을 원래의 표준 출력 스트림(콘솔)으로 복원합니다.
        System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));

        // 원래의 System.out을 사용하여 종료 메시지를 콘솔에 출력합니다.
        System.out.println("-- 끝4 --");

        // ByteArrayOutputStream에 저장된 출력 내용을 문자열로 변환하여 콘솔에 출력합니다.
        // 이를 통해 실제로는 화면에 출력되지 않았던 "안녕하세요"와 "반갑습니다"가 출력됩니다.
        System.out.println("출력: " + output.toString());

        // ByteArrayOutputStream 리소스를 해제하여 메모리 누수를 방지합니다.
        try {
            output.close();
        } catch (IOException e) {
            // IOException 발생 시, 런타임 예외로 래핑하여 던집니다.
            throw new RuntimeException(e);
        }
    }
}

콘솔 출력값

--시작4--
--4 --
출력: 안녕하세요
반갑습니다

실습 코드 2: 입력 스트림 테스트

키보드 입력을 미리 준비된 문자열로 대체하여 테스트할 수 있도록 작성한 코드입니다.

private static void lab2(){
	// 입력값을 미리 정의 합니다
    InputStream in = new ByteArrayInputStream("안녕\n잘가".getBytes());
    // 스캐너에 InputStream을 넣고 스캐너 객체로 만듭니다
    Scanner scanner = new Scanner(in);

	// 콘솔에 출력
    System.out.println("명령2) ");
    // 스캐너에 줄바꿈을 기준으로 첫번째 입력인 안녕을 가져옴
    String cmd = scanner.nextLine().trim();
    // 안녕 출력
    System.out.println("입력한 명령: " + cmd);

    System.out.println("명령2) ");
	// 스캐너에 안녕 다음으로 입력된 잘가를 가져옴
	cmd = scanner.nextLine().trim();
    // 잘가 출력
    System.out.println("입력한 명령: " + cmd);
}

콘솔 출력값

명령2) 
입력한 명령: 안녕
명령2) 
입력한 명령: 잘가

위 방법들을 응용하면
사용자가 콘솔로 볼 수 있는 문자열과 사용자가 콘솔에 입력하는 데이터를
별도의 스트림에 저장해서 테스트 코드에서 활용할 수 있습니다.

아래의 코드는 입출력 모두 응용해서 만든 테스트 코드입니다.

 @Test
    @DisplayName("registerWiseSay 호출 시 성공적으로 명언이 등록된다.")
    void testRegisterWiseSay_Success() {
        
        // Arrange: 테스트 환경 설정
        String simulatedInput = "멋진 명언\n위대한 작가\n"; // 사용자 입력 시뮬레이션 (명언과 작가)
        InputStream originalIn = System.in; // 기존 표준 입력(System.in) 백업
        System.setIn(new ByteArrayInputStream(simulatedInput.getBytes())); // 표준 입력 리다이렉션

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 출력 캡처를 위한 스트림 생성
        PrintStream originalOut = System.out; // 기존 표준 출력(System.out) 백업
        System.setOut(new PrintStream(outputStream)); // 표준 출력 리다이렉션

        WiseSayingController controller = new WiseSayingController(); // 테스트 대상 컨트롤러 객체 생성

        // Mocking: WiseSayingService를 Mock 객체로 생성
        WiseSayingService mockService = mock(WiseSayingService.class);
        // ReflectionTestUtils를 사용하여 WiseSayingController의 private 필드(wiseService)에 Mock 객체 주입
        ReflectionTestUtils.setField(controller, "wiseService", mockService);

        int generatedId = 1; // Mock 서비스가 반환할 ID 값 설정
        // Mocking: Mock 서비스가 register 메서드 호출 시 "멋진 명언"과 "위대한 작가"를 받아 generatedId를 반환하도록 설정
        when(mockService.register("멋진 명언", "위대한 작가")).thenReturn(generatedId);

        // Act: 테스트 대상 메서드 호출
        controller.registerWiseSay();

        // Assert: 테스트 결과 검증
        // Mock 서비스의 register 메서드가 올바른 파라미터로 한 번 호출되었는지 검증
        verify(mockService, times(1)).register("멋진 명언", "위대한 작가");

        // 출력 메시지 검증: 리다이렉션된 출력에 기대 메시지가 포함되었는지 확인
        String capturedOutput = outputStream.toString().trim();
        assertTrue(capturedOutput.contains("1번 명언이 성공적으로 등록되었습니다."));

        // Cleanup: 테스트 환경 복구
        System.setIn(originalIn); // 표준 입력(System.in) 복구
        System.setOut(originalOut); // 표준 출력(System.out) 복구
    }
profile
지속가능한 사회적 가치의 현실화

1개의 댓글

comment-user-thumbnail
2024년 11월 28일

표준 입출력 파트는 봐도봐도 어려운 것 같아요 ㅜ 명언앱 TDD로 다시 만들때엔 혼자 더 자세히 봐야겠습니다😅 오늘도 좋은 내용 잘 보고 갑니다

답글 달기