2013-07-03 28 views
0

我想知道是否有可能測試某種依賴於靜態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()(我知道有什麼可考,但是這只是一個例子)在Windows上的方法,如果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)。