Java Eclipse環境のtestソースとmainソースのpropertiesファイルの参照順序をEclipseの設定で切り替える


testソースとmainソースの参照順序について

今更な感じだが、Eclipse環境で以下のようなディレクトリ構成の場合、

src/main/
  ├─ java/jp/co/hogehoge/
  │   └─ fugafuga.java
  └─ resources/
      └─ *.properties

src/test/
  ├─ java/jp/co/hogehoge/
  │   └─ fugafugaTest.java
  └─ resources/
      └─ *.properties

Eclipse上のクラスパスは

    src/main/java
    src/main/resources
    src/test/java
    src/test/resources

となるが、Eclipseから実行する場合はJUnitテスト実行時なのでresourcesの参照は

    src/test/resources/*.properties

本番環境で実行する場合は

    src/main/resources/*.properties

を参照したい。
通常本番環境時は管理者がpom.xmlをきちんと設定してmain/resourcesを参照するようになっているので問題ないが、たまにローカル環境での設定がされていない場合があると期待したtest/resourcesを参照しなくてハマる事があるので念のためメモ。

※もちろんローカル環境で直したクラスパス設定は間違っても設定ファイルをコミットしないように.ignore等に設定しておくなりする事。その辺は自己責任で。

サンプル環境

以下のような構成でmessage.propertiesを参照してみる。

src/main/message.properties
# メイン側メッセージ
name=メインから取ったよ
src/test/message.properties
# テスト側メッセージ
name=テストから取ったよ

メッセージプロパティー取得プログラム

MessageProperties.java
package jp.co.ivynetwork.messages;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * message.propertiesの値を返すサンプル処理.
 *
 * @author boss_ape
 */
public class MessageProperties
{
    private static Properties conf = new Properties();

    private static MessageProperties instance = new MessageProperties();

    /**
     * 唯一のインスタンスを返す.
     */
    public static MessageProperties getInstance()
    {
        return instance;
    }

    /**
     * コンストラクタ.<br>
     * シングルトンのためprivate。ファイルから内容を読み込む
     */
    private MessageProperties()
    {
        // クラスローダを使ってクラスパスからの相対パスでファイルを指定
        String fileName =
                MessageProperties.class.getClassLoader().getResource("message.properties").getPath();
        try (FileInputStream fi = new FileInputStream(fileName)) {
            // ファイルから読み込み
            conf.load(fi);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * message.peropertiesからnameの値を取得する
     *
     * @throws IOException ファイルが開けない
     */
    public String getName() throws IOException
    {
        return conf.getProperty("name");
    }
}
MessagePropertiesTest.java
package jp.co.ivynetwork.messages;

import static org.junit.Assert.*;

import java.io.IOException;

import org.junit.Test;

/**
 * MessagePropertiesクラステスト.
 *
 * @author boss_ape
 */
public class MessagePropertiesTest
{
    /** メッセージプロパティオブジェクト. */
    private MessageProperties prop = MessageProperties.getInstance();

    /**
     * MessagePropertiesの内容確認.
     */
    @Test
    public void testMessagePropertiesの内容確認()
    {
        try {
            System.out.println(prop.getName());
            assertTrue(true);
        } catch (IOException e) {
            e.printStackTrace();
            fail();
        }
    }
}

メインとテストそれぞれ参照順序を変えてみる

ビルドパス
(パッケージエクスプローラからプロジェクトを右クリック⇒ビルド・パス⇒ビルド・パスの構成⇒順序およびエクスポート)

main/message.propertiesを参照したい場合、mainをビルドパスの上に持ってくる

結果

testmessage.propertiesを参照したい場合、testをビルドパスの上に持ってくる

結果


※ちなみにpom.xmlでtest時のみtest/resourcesを参照する設定は以下のように追記する

pom.xml
<testResources>
   <testResource>
       <directory>src/test/resource</directory>
       <includes>
           <include>**/*.xml</include>
       </includes>
   </testResource>
</testResources>