2016-09-09 63 views
4

我正在努力創建一個測試來驗證加載屬性文件的ServletListener。我測試過運行的應用程序,它工作正常,它發現classpath中的文件。但我不知道如何爲它創建一個測試。我的想法是創建一個帶有測試屬性的臨時文件,然後驗證該屬性是否放入System properties。但是我總是無法在正確的位置創建文件。getResourceAsStream(「文件」)在測試中運行時進行搜索?

我試過在/target/test-classes或直接在應用程序的根目錄下創建文件,但它從來沒有找到它。任何想法?

這是我想測試代碼:

public class PropertyReadingListener implements ServletContextListener { 

    public static final String PROFILES_PROPERTIES = "profiles.properties"; 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     Properties propsFromFile = new Properties(); 
     try { 
      propsFromFile.load(getClass().getResourceAsStream(PROFILES_PROPERTIES)); 
     } catch (final Exception e) { 
      log.warn("Unable to find {}, using default profile", PROFILES_PROPERTIES); 
     } 
     propsFromFile.stringPropertyNames().stream() 
      .filter(prop -> System.getProperty(prop) == null) 
      .forEach(prop -> System.setProperty(prop, propsFromFile.getProperty(prop))); 
    } 
} 

感謝。

+1

好的單元測試可以通過嘲笑合作類的行爲來消除外部依賴(如文件)。這是一個很好的做法,因爲它允許您編寫一個可以輕鬆運行的測試(即,您不必擔心部署文件或將應用程序打包到JAR中)。 – EJK

+1

你正在用maven構建yor項目嗎?然後你可以把一個測試屬性文件放到src/test/resources中。這隻適用於測試類。你會加載它與getResourceAsStream(「/」+文件名) –

回答

0

Different ways of loading a file as an InputStream

基本上當你做一個的getClass()的getResourceAsStream它會在包類文件的..所以,如果你的PropertyReadingListener是com.company.listeners.PropertyReadingListener那麼它的外觀在com/company/listeners中爲屬性文件。

對於可測試性,我將通過在一個InputStream進入偵聽方式測試可以創建一個convienent方式輸入流和在代碼中類的實際用戶可以在InputStream的通過從的getResourceAsStream

+0

感謝您的鏈接。這澄清了使用類和類加載器加載文件之間的區別。這基本上是我沒有做到的,使用類加載器。 – Kilian

+0

我在最後嘗試了很多東西,我沒有嘗試使用「/」和getClass()。getResourceAsStream()的路徑。我現在已經嘗試了兩種選擇,他們工作。 – Kilian

1
返回

getResourceAsStream(「file」)在測試中運行時搜索的位置在哪裏?

假設你正在談論的JUnit ....

除非你已經做了時髦,單元測試將被默認的類加載器加載,這意味着正常的JVM類路徑進行搜索。

(JUnit 4中,您可以使用不同的類裝載器:看https://stackoverflow.com/a/9192126/139985


但我始終無法創建在正確的地方文件。

看來你真正的問題是理解Java類路徑和類路徑搜索是如何工作的。如果你明白這一點(並且你知道JUnit runner的實際類路徑是什麼),那麼它應該很明顯放在屬性文件的哪裏,以便類加載器可以找到它。

+0

你說得對,我不知道它是如何工作的。我以爲它應該從類路徑加載,但我不知道它取決於您是使用類還是類加載器來完成它。 – Kilian

1

假設你正在使用maven,把你的屬性文件的位置:

src/test/resources/foo.properties 

Maven的資源插件將放置文件(可能是過濾)副本

target/test-classes/foo.properties 

所述測試classes目錄位於類路徑中,因此您可以像這樣引用文件(請注意文件名前面的斜線):

... getResourceAsStream("/foo.properties"); 
相關問題