web-dev-qa-db-ja.com

テストのためのスプリングジュニットロードアプリケーションコンテキスト

WEB-INFディレクトリにいくつかのXMLファイルがあります。

  • lyricsBaseApp-servlet.xml
  • hibernate.xml
  • dataSource.xml
  • beans.xml

サーブレットxmlは他のxmlファイルをインポートします。

<import resource="dataSource.xml"/>
<import resource="hibernate.xml"/>
<import resource="beans.xml"/>

Junit4 JukeboxTestクラスにスプリング設定全体を含めたいです。デフォルトのファイル名を使用して、JukeboxTest-content.xmlファイルを作成しました。そして最後に、そこに何を置くべきか分かりません...

私はもう試した:

<import resource="/WEB-INF/dataSource.xml"/>
<import resource="/WEB-INF/hibernate.xml"/>
<import resource="/WEB-INF/beans.xml"/>

または

<import resource="classpath:./WEB-INF/dataSource.xml"/>
<import resource="classpath:./WEB-INF/hibernate.xml"/>
<import resource="classpath:./WEB-INF/beans.xml"/>

そして他のいくつかのアイデアがすべて失敗しました。誰かがそれらのファイルにアクセスする方法と、春がそれらのファイルパスをどのように解釈するかを教えてもらえますか?

26
ducin

オプション1(ベストプラクティスであるため、推奨されます):
構成ファイルを_WEB-INF_の下でリファクタリングし、(統合テストからもアクセスしたい)共通部分を_src/main/resources/_に移動します。次に、テスト固有の構成ファイルを_src/test/resources/_に書き込みます(テストコンテキストをアセンブルするために_src/main_からいくつかの異なる構成ファイルをインポートする必要がある場合は、これをスキップし、できれば_@ContextConfiguration_を使用します)。

オプション2(ハック):
次のような参照を使用します。

_@ContextConfiguration("file:src/main/webapp/WEB-INF/dataSource.xml")
_

オプション3(ハック):
Mavenプロジェクトがある場合は、_maven-surefire-plugin_(テストフェーズで使用)を構成して、テストの実行中に_src/main/webapp_を追加のクラスパス要素として宣言できます。

後者の2つのオプションは、_src/main/webapp_の下のファイルは単にクラスパス上にあるはずがないため、ハックと見なされます。

今、詳細な説明:

これらのファイルを_classpath:/WEB-INF/*.xml_として参照できない理由は、それらが実際にクラスパス上にないためです。 webappがどのようにパッケージ化されているか、そしてクラスパスで正確に何が終わるかを理解することが重要です。デフォルトのMavenプロジェクト構造を想定:

  1. _src/main/Java_のJavaクラスは、コンパイル後に_/WEB-INF/classes_に移動します。
  2. _src/main/resources_のリソースも_/WEB-INF/classes_に移動します。
  3. プロジェクトの依存関係は_/WEB-INF/lib_に移動します。
  4. _src/main/webapp_にあるものはすべて_/_(パッケージのルート)に移動します。これは、もちろん_src/main/webapp/WEB-INF_のすべてのファイルが_/WEB-INF_に移動することを意味します。

知っておくべき最も重要なことは、クラスパスには_/WEB-INF/classes_と、_/WEB-INF/lib_の各jarごとに1つのエントリのみが含まれることです。したがって、これらの2つの場所の外側のリソースは、クラスローダーからは完全に見えません。これは、XML構成ファイルの直下_/WEB-INF_にも当てはまります。これが、参照_classpath:/WEB-INF/dataSource.xml_が機能しない理由です。

クラスパスから到達できない場合、これらのxml構成ファイルはSpringによってどのようにロードされるのでしょうか?答えは簡単です:ユニット/統合テストだけを実行するのではなく、webappを起動すると、ServletContext(Servlet APIからの実際のクラス)へのアクセスを提供するServlet Containerで実行されます。したがって、ServletContext.getResourceAsStream()を使用してこれらのファイルをロードします。理解の鍵は、このメソッドの javadoc からの次の引用です。

このメソッドは、クラスローダーを使用するJava.lang.Class.getResourceAsStreamとは異なります。このメソッドにより、サーブレットコンテナは、クラスローダーを使用せずに、任意の場所からサーブレットがリソースを利用できるようになります。

申し訳ありませんが、これは非常に長くなりますが、それは全体の話です...

83
zagyi

これを試して

@ContextConfiguration(locations = {"classpath:**/dataSource.xml",
                               "classpath:**/hibernate.xml", 
                               "classpath:**/WEB-INF/beans.xml"})
12
Kris