2013-05-28 2 views
2

멀티 스레딩 시스템의 기능 테스트가 있습니다. 문제는 시스템이 System.exit을 사용하여 junit 테스트가이 오류를 포착하지 않는다는 것입니다. 그래서 다른 스레드에서도 System.exit이 호출 된 곳에서 테스트를 실패합니다.다른 스레드의 System.exit에서 JUnit 테스트가 실패합니다.

Java: How to test methods that call System.exit()?을 사용하여 System.exit에서 JVM 중지를 방지하고 대신 ExitException을 throw합니다. 또한이 예외를 수집하기 위해 http://blog.cedarsoft.com/2011/12/junit-rule-fail-tests-on-exceptionsfailed-assertions-in-other-threads/을 사용했습니다. ExitException 후 실패 할 경우 테스트를 중단하고 싶습니다. 그러나이 예외는 현재 스레드 만 중지합니다. ExitException을 throw하기 전에 junitThread.interrupt()를 호출하려고 시도했지만 간단한 테스트에서만 완벽하게 작동합니다.

스레드 작성 코드를 수정할 수없는 경우 어떻게하면 스레드에서 ExitException을 throw하여 junit 테스트를 중단 할 수 있습니까?

+0

아마도 이것은 당신에게 도움이 될 수 있습니다 : http://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit –

답변

1

System.exit()입니까? 그리고 단위 테스트로 다루는 레벨에서 System.exit()을 부르는 이유는 무엇입니까?

종료 코드를 테스트하려면 테스트가 프로세스를 생성하고 계획대로 종료했는지 확인하십시오. 다른 기능을 테스트하려면 테스트중인 코드에서 부작용이 발생하지 않도록 응용 프로그램을 구조화하십시오.

일반적으로 개별 스레드가 System.exit()이라고 부르는 것은 잘못된 아키텍처의 강력한 표시기입니다. 어떤 스레드가 다른 스레드에 정리할 기회를주지 않고 전체 응용 프로그램을 즉시 죽일 수 있다면 곧 어떤 문제가 발생할 수 있습니다.

스레드가 System.exit() 대신에 전역 차단 처리기를 호출 (테스트에서 재정의 할 수 있음)하면 해당 기능을 테스트하는 데 문제가 없습니다.

업데이트 : 레거시 코드를 다룰 때 내 첫 번째 단계는 System.exit()을 테스트에서 바꿀 수있는 장소로 분리하는 것입니다. 예 : 이 같은 클래스를 생성 :

// "Singleton" with replaceable instance 
public class ShutdownHandler { 
    private static ShutdownHandler instance = new ShutdownHandler(); 

    public static ShutdownHandler getInstance() { 
     return instance; 
    } 

    public synchronized void shutdown() { 
     // default implementation 
     System.exit(); 
    } 

    public static void setInstance(ShutdownHandler newInstance) { 
     // (probably also check that this is only called in a test environment) 
     instance = newInstance; 
    } 
} 

그런 다음 ShutdownHandler.getInstance().shutdown() 모든 System.exit() 통화를 대체합니다. 그것은 응용 프로그램 기능을 전혀 변경하지 않습니다. 그러나 이제는 테스트에서 ShutdownHandler 인스턴스를 구현하는 대신 일부 플래그 +를 설정하여 종료 대신 예외를 throw하는 구현으로 바꿀 수 있습니다. 그러면 테스트에서 해당 플래그를 검사하여 앱이 종료되었는지 여부를 확인할 수 있습니다.

또한 Robert C Martin의 "Working Code With Legacy Code"를 사용하여 예전의 난장판을 다루기 쉬운 것으로 바꾸는 방법에 대한 더 많은 아이디어를 얻을 수 있습니다.

+0

이 코드는 오래되었고'System.exit()'나를 놀라게했다. – nickotinus

관련 문제