2010-11-30 7 views
3

私は最近、私の単体テストのシステムプロパティを読み込むための解決策を見出しました。テストを個別に実行している場合はうまく動作しますが、テストスイート全体を実行すると失敗します。誰かが私に理由を教えてくれますか?テストのシステムプロパティをロードする

最初のステップは、テスト・アプリケーション・コンテキストをロードすることである。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "/applicationContext-test.xml") 

次のステップは、システムプロパティをロードするクラスを作成することである。

import java.io.InputStream; 
import java.util.Properties; 

import javax.annotation.PostConstruct; 

import org.springframework.core.io.Resource; 

public class SystemPropertiesLoader{ 

    private Resource resource; 

    public void setResource(final Resource resource){ 
     this.resource = resource; 
    } 

    @PostConstruct 
    public void applyProperties() throws Exception{ 

     final Properties systemProperties = System.getProperties(); 

     final InputStream inputStream = resource.getInputStream(); 

     try{ 
      systemProperties.load(inputStream); 
     } finally{ 
      inputStream.close(); 
     } 
    } 
} 

最後のステップは、リストにあります

<bean class="com.foo.SystemPropertiesLoader"> 
    <property name="resource" value="classpath:localdevelopment_Company.properties" /> 
</bean> 

私がテストスイートを実行すると、私のテストのいくつかは、システムのプロパティに依存していますが、失敗します。私が特定のテストに行ってそれを実行すると、それは合格となります。私はそれをデバッグし、SystemPropertiesLoaderのコードが実行されていることを確認しました。他のすべてのBeanはコンテキストから正常に取得されています。しかし、アクセスしようとすると、それらはすべてnullになるので、プロパティは正しくロードされていません。助言がありますか?

答えて

2

実際、問題はPropertiesクラスの値が静的に定義されていることでした。したがって、解を破ったケースがあります。

  1. テストAが実行されました。テストAはapplicationContext-test.xmlをロードしませんが、で、Propertiesクラスの値を使用するコードを呼び出します。
  2. これで、Propertiesクラスのすべての値が永続的に定義されました。
  3. テストBが実行されます。テストBは、applicationContext-test.xmlをロードします。
  4. SystemPropertiesLoaderが実行され、システムプロパティに値がロードされます。
  5. 値はPropertiesクラスから取得されますが、静的に定義されて以前に割り当てられているため、システムプロパティの値は決してそこに入りません。

最後に、最も良い解決策は、Propertiesクラス内にデフォルト値を定義することでした。

0

各テストケースが新しいJVMを生成し、Systemプロパティがテストケースごとに設定されていない可能性がありますか?

あなたのJUnitテストクラスでsetUp()メソッドとtearDown()メソッドを活用しようとしているかもしれません。

3

いくつかのアイデア:

  1. あなたは、ユニットテストしているのに、なぜ、個々のテストケースで必要なプロパティを設定していない場合。バネを使ってグローバル変数を設定するという点はありません。
  2. なぜシステムプロパティを使用しますか? Springは、Beanにインジェクトでき​​るプロパティオブジェクトを管理します。それらはappContext.xmlで設定でき、システムプロパティを使用してそこで初期化することもできます(PropertyPlaceHolderConfigurerを参照)。あなたのコードにシステムプロパティをアクセスさせることは、春の哲学に反します。
  3. ファイルからシステムのプロパティを設定することは、むしろ間違っています。通常は、システムプロパティを使用してプロパティファイルの設定を上書きします。
+0

ありがとうございます!私はPropertyPlaceholderConfigurerを試してみました。このアプローチをアプリケーション全体に適用することに同意するかどうかを確認するために、他の開発者がそれを実行する必要がありますが、それは間違いなく問題を解決します。 – Samo

+0

私はこのアプローチをさらに検討しており、これが私たちのためにうまく機能する方法があるかどうかは疑問です。私たちはプロパティを静的に参照できるようにしたいと思いますが、Springに静的な値を初期化するのは悪夢です。クラスをインスタンス化する必要がなくなるたびにクラスをインスタンス化する必要はなく、すべてのプロパティを持つBeanを使用する必要もありません。静的にアクセス可能な不変の文字列が必要です。助言がありますか? – Samo

+0

こんにちはSamo、すべてのプロパティでBeanをインスタンス化してみませんか?アプリスコープの場合は、一度しかインスタンス化されません。また、(フィールドやゲッターのように)実際のjavaプロパティを持つ、あなたのパラメータ用のBeanを持つことを検討するかもしれません。次に、あなたのアプリケーションがjavadocで取得するパラメータを文書化することができます。 –

関連する問題