0

私は現在、あるファイルとの間でプロセス構成をロード/保存する機能をチェックするJUnitテストに取り組んでいます。特定の構成ファイルがリソースに存在する場合、機能はファイルからパラメーターをロードします。それ以外の場合、機能は新しい構成ファイルを作成し、クラスにコード化されたデフォルト構成を保持しようとします。現在、.class.getResource()メソッドを使用して、構成ファイルが存在するかどうかを確認し、必要な情報を取得しています。このアプローチは、Mavenの「test-class」ディレクトリと「class」ディレクトリの両方で正常に機能することが証明されています。ただし、ファイルが存在しない場合、つまり.class.getResource()メソッドがリソースがまだ存在しないためにnullを返す場合に、デフォルト構成を保存しようとすると問題が発生します。

特定のオブジェクトがテストとして実行されているのか、本番環境で実行されているのかを評価する機能をコーディングする方法はありますか?より正確には、リソースファイルへの相対パスを作成して、の実行モードに応じて本番リソース(../classes/...)またはテストリソース(../test-classes/..)のいずれかを指すようにするにはどうすればよいですか。現在のプロジェクトはどれですか?

私の質問は次のようなものです。Mavenが管理するJavaプロジェクトでテストリソースファイルを見つけるにはどうすればよいですか?しかし、私はそれが新しいスレッドを保証するのに十分異なると思います。

4

2 に答える 2

0

次のことをしたいようです。

コードを実行すると、構成ファイルを読み込もうとします。構成ファイルが見つからない場合は、構成ファイルを作成します。ひねりはそれです

  • コードを「本番モード」で実行している場合(コードの性質に応じてexec-maven-pluginやjetty-maven-pluginなどを使用していると思います)、構成ファイルを${projectに配置します。 build.outputDirectory}

  • コードを「テストモード」で実行している場合(たとえば、surefireまたはfailsafeを介して)、構成ファイルを${project.build.testOutputDirectory}に配置する必要があります。

私がすることは、ServiceLoaderパターンを使用することです。

構成の保存を担当するConfigFileStoreインターフェースを作成します。

ConfigFileStoreFactoryは、そのインターフェイスを実装するすべてのサービスを列挙します(ServiceLoader APIを使用して、すべての/META-INF/services/com.yourpackage.ConfigFileStoreリソースを取得し、それらからクラス名を抽出します。実装が登録されていない場合は、インスタンス化されます。 getClass()に基づくパスにファイルを格納するデフォルトの実装(つまり、$ {project.build.outputDirectory}に到達するために逆方向に作業することは、クラスがJARにバンドルされる場合を処理する必要があることに注意してください。このような場合、構成ファイルがJARに隣接して格納される可能性があると想定します)

注:デフォルトの実装は/ META-INF/servicesに登録されません

次に、src / test / javaでデフォルトの実装を拡張し、その拡張された実装をsrc / test / resources / META-INF / services/com.yourpackage.ConfigFileStoreに登録します。

これで、クラスパスにテストコードがあるコードを実行すると、テストバージョンが見つかります。これは、テストクラスパスの/ META-からのものであるため、$ {project.build.testOutputDirectory}からクラスのgetClass()を取得します。 INF/サービス。

クラスパスにテストコードがないコードを実行する場合、デフォルトの実装は$ {project.build.outputDirectory}からクラスのgetClass()を取得します。

あなたがやりたいことをする必要があります。

于 2012-08-14T08:00:11.987 に答える
0

私があなたを正しく理解していれば、本質的にあなたの問題は、アプリケーションの動作を決定する特定のファイルを(通常、および単体テスト中に)読み取るMavenプロジェクトがあることです。そのファイルが存在しない場合は、アプリケーションによって作成されます。

の問題はClassLoader.getSystemResource(...)、実際には単一のディレクトリをスキャンしていないことです。代わりに、Java のクラスパスを調べて、その特定のリソースの場所を特定します。クラスパスに複数のディレクトリがある場合、ファイルが配置される可能性のある多くの領域があります。

ある意味では、それ.getSystemResource(...)は一方通行です。ファイルの場所を検索することはできますが、適切な場所に配置することはできません。

*では、ファイルを正しい場所に配置する必要がある場合はどうでしょうか? *

基本的に 2 つのオプションがあります。

  1. ファイルの場所をハードコードする: 誰もそれを好まない.
  2. クラスパスでスキャンされた場所は、クラスローダーに渡されます。たとえば、最初のものを使用して、そこにファイルを作成できます。

2 番目のオプションは実際には悪いものではありません。このサンプルコードを見てください。

    final Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources("");
    if(! urls.hasMoreElements()) {
        LOG.error("No entries exist on the class path!");
        System.exit(1);
    }
    final File configFile = new File(urls.nextElement().getFile(), "config.xml");
    configFile.createNewFile();
    LOG.info("Create a new configuration file: " + configFile.getPath());
    System.exit(0);

これにより、構成ファイルがターゲットフォルダー内にあることが解決されました。..\target\classes\config.xml

何をするかはあなた次第です。さらに必要な場合は、さらにヒントとアドバイスを提供させていただきます。

于 2012-08-13T23:07:46.963 に答える