2011-11-12 2 views
2

사용자 입력을 위해 System.in에서 읽는 클래스에 대해 테스트를 실행하는 방법은 무엇입니까? 예를 들어Java에서 입력을 읽는 단위 테스트 클래스를 어떻게 만들 수 있습니까?

:

나는 어쩌면 메인 클래스를 서브 클래스와 getUserInput 다시 스크립트 답을 공급하는 overridding 생각했습니다
private int getUserInput() { 
    Scanner scanner = new Scanner(System.in); 

    System.out.print("What's ya input? [1-3]: "); 
    return scanner.nextInt(); 
} 

. 입력을 결정하기 위해 System.out을 읽어야 할 경우에는 작동하지 않습니다.

나는 몇 시간을 쓰레드를 보면서 보냈지 만 이것들을 사용하는 방법도 알지 못했다.

답변

13

를 글쎄, 당신은 System.setIn()를 사용하여 System.in을 대체 할 수 있지만 그 접근 방식을 선호하지 않을 수 있습니다. 글로벌 상태를 설정 항상 테스트를 좀 더 깨지기 쉽고 불투명하게 만듭니다.

대신에 실제로 시도해야합니다. b 예를 들어 읽으려는 InputStream을 클래스 생성자를 통해 클래스에 삽입하여 종속성을 다시 잡아라. 일단 당신이 그것을 할 때, 단위 테스트를 할 때 정적 데이터에서 읽는 자신의 InputStream을 전달할 수 있으며 생산 코드에서 System.in을 주입 할 수 있습니다.

+1

+1은 의존성 주입에 사용됩니다. 일단 이것을 이해하면 객체 디자인이 다르게 보입니다. –

+0

전역 [주변] 상태를 읽는 것은 항상 나쁜 설계입니다. 많은 영향 중 하나는 테스트를 더 어렵게 만드는 것입니다./"주입"은 무의미한 용어입니다. 그것은 단지 그들이 사용되기로되어있는 방식으로 생성자를 사용하는 것입니다. 입력 객체에 대한 액세스 권한은 * 부여됩니다. –

+0

@Tom : 나는 이것이 "의존성 주사"의 형태이기 때문에 "주입"이라고 말했습니다. 종속성을 생성자를 통해 전달하는 것을 포함하지 않는 다른 형태의 종속성 삽입이 있습니다. –

2

System.in 및 System.out에 대한 참조를 변수 또는 테스트에서 재정의 할 수있는 결과 값으로 설정하십시오 (ByteArrayInput/OutputStream과 같은 다른 스트림을 사용하거나 사용할 수없는 경우). System.setOut 및 System.setIn는 기본 스트림을 교체하여 테스트를 실행, 출력을 확인하고 다시 설정합니다.

+0

다른 값을 할당 한 후 System.in을 어떻게 재설정 할 수 있습니까? – panny

+1

'PrintStream oldSystemIn = System.in; System.setIn ('...'); '...'; System.setIn (oldSystemIn);'- preferrably try ... finally 블록에서. – mihi

2

사용자 입력을 모방 한 Mock 개체를 만들 수 있습니다.

관련 문제