2013-07-03 2 views
0

static final 필드에 종속적 인 클래스를 어떻게 테스트 할 수 있는지 궁금합니다. 예를 들어, 나는 다음과 같은 클래스가 :테스팅 클래스는 정적 final 필드에 종속 됨

public final class Foo 
{ 
    private static Foo instance; 
    public static final String BAR_FILE = "/usr/bin/bar.bar"; 

    private Foo() 
    { 
     loadBar(); 
    } 

    public static synchronized Foo getInstance() 
    { 
     if (instance == null) 
     { 
      instance = new Foo(); 
     } 
     return instance; 
    } 

    private void loadBar() 
    { 
     final Properties prop = new Properties(); 
     try 
     { 
      final FileInputStream fis = new FileInputStream(BAR_FILE); 
      prop.load(fis); 
      fis.close(); 
     } 
     catch (final IOException ex) 
     { 
      System.out.println("Exception!"); 
     } 
    } 
} 

그래서 테스트 할 수있는 방법 getInstance() (I 테스트 할 아무것도 알고 있지만, 이것은 단지 예입니다) BAR_FILE는 하드 코드 일부 UNIX 기반에 동일한 경우 창에 방법 스타일 경로입니다. 리플렉션을 통해이 필드를 변경하려고 시도했지만 행운이 없었으며 더 나아가 this 논의에 따르면 불가능했습니다. 어떤 도움을 주셔서 감사합니다!

+0

테스트 방법을 사용하기 전에 정적 필드 이름을 딴 파일을 만듭니다. –

+3

근본적으로이 클래스는 테스트 친화적 인 방식으로 설계되지 않았습니다. 싱글 톤을 피하기 위해 그것을 바꿀 수 있다면 정말 도움이 될 것입니다 ... 동일한 파일을 두 번로드하는 것을 피하기 위해 공장을 쉽게 넣을 수 있습니다. 그리고 그 팩토리는 정말로 원한다면 싱글 톤이 될 수 있습니다. –

+0

@SotiriosDelimanolis, 당신이 의미하는 것을 이해하지 못했습니다. –

답변

0

비즈니스 로직을 구조적 로직과 분리하십시오. 클래스는 생성 방법을 신경 쓰지 않아도되며, 공장 또는 DI 프레임 워크에 그대로 두어야합니다.

는 DI 프레임 워크를 사용이 매우 간단합니다 : 공장을 사용

@Singleton 
public final class Foo { 
    public Foo(String fileName) { loadBar(fileName);} // Use in tests 
    public Foo() { loadBar(DEFAULT_FILENAME);} 
    private void loadBar(String file) 
    { 
     // SNIP 
    } 
} 


public class ThingieThatUsesFoo { 
    public ThingieThatUsesFoo(Foo foo) { ... } // The DI framework (Guice/Spring) will handle the details of WHAT gets injected. 
} 

조금 더 노력하지만 많은입니다. 당신이 모의를 주입하고 당신이에 통과하지 못한 영리하려면 지금 (읽을 수있는 파일을 설정할 수있는 푸를 테스트하는 것은 쉽다 수있는 푸의 클라이언트를 테스트 두 경우 모두

// You could make FooFactory a singleton if that is your thing. 
public class FooFactory { 
    private Foo fooInstance = new Foo(); 
    public Foo getFoo() { 
     return fooInstance; 
    } 
    public void setFooForTestingOnly(Foo fooInstance) { ... } // Set this to a mock or what have thee when testing clients. 
} 

쉽습니다 파일이지만 Reader 또는 InputStream).

관련 문제