Spring > Testing

Unitテスト

  • SpringでDIを使えばPojoだからJUnit,TestNGでテストできる
  • モックオブジェクトを使う
  • Unitテストはすばやく終わらないとだめ

モックオブジェクト

  • JNDI SPI
    • org.springframework.mock.jndi
    • JavaEEコンテナのデータソースとか
  • Servlet API
    • org.springframework.mock.web
    • Spring Web MVCで使われるオブジェクトのモック
    • Webコンテキストとコントローラのテスト
  • Portlet API
    • org.springframework.mock.web.portlet
    • Spring Portlet MVCで使われるオブジェクトのモック

サポートクラス

  • ReflectionTestUtils
    • 非publicなフィールドへの代入、setterの呼び出しとか
  • ModelAndViewAssert
    • Spring MVCのModelAndView をテストできる
    • Controllerのテストには、MockHttpServletRequestとかMockHttpSessionとかも使える

Integration テスト

  • デプロイなしで実行
  • インフラ部分につなげずに実行
  • IoCコンテナを正しくつなぐ
  • データアクセステストを正しくおこなうこと
    • SQL、Hibernateクエリ、JPAマッピングの妥当性
  • spring-test:org.springframework.test
    • APサーバとか配置環境に依存しない
    • Cuctusとかリモートにつなげるテストより速い

利用できる機能

  • テスト実行の間でのDIコンテナキャッシュの管理
    • 普通は1テストスィートで1回初期化
    • でも、特殊な場合も扱える
  • テスト用インスタンスのDI
    • いろいろなテストシナリオでアプリケーションコンテキストを再利用できる
  • テスト用のトランザクション管理
    • DBに接続するテストでデータへの影響をなくせる。
    • トランザクション内にあるものとしてテストがかける。
  • テストを書くのをサポートしてくれるクラス
    • テストフレームワークへのフック
    • 以下にアクセスできるインスタンス変数やメソッド
      • ApplicationContext ビーン参照とか
      • SimpleJdbcTemplate テスト実施前後のDB状態確認とか

JDBC Testing Support

  • SimpleJdbcTestUtils
    • JDBCのテストを簡単に実行できるようにしてくれるユーティリティ
    • AbstractTransactionalJUnit4SpringContextTestsも内部で使っている

Annotations

  • Spring Testing Annotations
    • @ContextConfiguration
      • クラスレベルで、コンテキストのロードの設定をする。(locations or classes 属性)
    • @ActiveProfiles
      • テスト用のApplicationContextを読み込んだときに。どのビーン定義プロファイルをアクティブにするか
    • @DirtiesContext
      • テスト実行時にApplicationContextが変更され、テスト終了時にクローズされる
      • ダーティマークがつられるタイミング(ダーティマークがつくとコンテキストはキャッシュから破棄されリロードされる)
      • クラスレベル、classMode=AFTER_CLASS⇒テストクラス実行後
      • クラスレベル、classMode=AFTER_EACH_TEST_METHOD⇒テストクラスのテストメソッド実行後
      • メソッドレベル⇒テストメソッド実行後
    • @TestExecutionListeners
      • クラスレベル
      • TestContextManagerに登録されるリスナを設定
    • @TransactionConfiguration
      • トランザクションを使うテストの設定
      • "transactionManager"という名前のトランザクション管理ビーンがあり、ロールバックが必要ないときは不要
    • @Rollback
      • テストメソッドのロールバックの振る舞いを指定
      • クラスレベルで定義されたロールバックフラグの振る舞いを上書く
    • @BeforeTransaction
      • トランザクションのテストメソッド(@Transactional付)の実行前に実施される
    • @AfterTransaction
      • トランザクションのテストメソッド(@Transactional付)の実行後に実施される
  • Spring TestContext Frameworkで使える標準アノテーション
       @Autowired
       @Qualifier
       @Resource (javax.annotation) if JSR-250 is present
       @Inject (javax.inject) if JSR-330 is present
       @Named (javax.inject) if JSR-330 is present
       @PersistenceContext (javax.persistence) if JPA is present
       @PersistenceUnit (javax.persistence) if JPA is present
       @Required
       @Transactional
    
  • Spring JUnit Testing Annotations
    • SpringJUnit4ClassRunnerを使ったときに利用できるアノテーション
    • @IfProfileValue
      • クラスレベル、メソッドレベル
      • テストの有効/無効をProfileValueSourceから得られる値によって切りかえ
    • @ProfileValueSourceConfiguration
      • クラスレベル
      • @IfProfileValueで判断対象になるProfileValueSourceを指定(デフォルトはSystemProfileValueSource )
    • @Timed
      • テスト実行時間(繰り返し、setup、teardownも含む)の上限(milli sec)を指定
    • @Repeat
      • テストの繰り返し実行

Spring TestContext Framework

  • ジェネリクス、アノテーションを使った単体、結合試験のサポート
  • CoC重視

主要なクラス

  • TestContext
    • 実行中テストのコンテキスト情報
    • コンテキストの管理、キャッシュサポート
    • ContextLoaderへの委譲
  • TestContextManager
    • テストメソッド実行毎に生成
    • 1つのTestContextを管理(ステータスの更新とか)
    • TestExecutionListenerに委譲(テスト実行イベント発信)
  • TestExecutionListener
    • テスト実行イベントに対するリスナ
    • DIとかトランザクション管理をしてテストを実行する
    • 継承で登録されるリスナも引き継がれる
    • DependencyInjectionTestExecutionListener:テストインスタンスのDI
    • DirtiesContextTestExecutionListener:@DirtiesContextの扱い
    • TransactionalTestExecutionListener:トランザクションのテスト
  • ContextLoader
    • ApplicationContextの読み込み
  • SmartContextLoader
    • 3.1以降
    • コンフィグレーションクラスの指定
    • アクティブなビーン定義プロファイルの設定
    • DelegatingSmartContextLoader
    • AnnotationConfigContextLoader
    • GenericXmlContextLoader
    • GenericPropertiesContextLoader

テストコンテキストの管理

  • AppicationContextをテストクラスから使いたい場合は、ApplicationContextAwareを実装するか、@ContextConfigurationをつけて、DIする
  • TestContextフレームワークを使うにはテストクラスに@ContextConfigurationを付ける
  • @ContextConfigurationのlocations属性でXMLファイルのパス(クラスパス、リソースURL)を指定
  • XMLファイルのデフォルトパス(locations属性の指定なし)
    [テストクラスと同じクラスパス]/[テストクラス名]-context.xml
    
  • @ContextConfigurationのclasses属性でコンフィグレーションクラスを指定
  • コンフィグレーションクラスのデフォルト(classes属性の指定なし)= テストクラスのstatic inner クラス(private不可)
  • XMLとコンフィグレーションクラスを両方使いたい場合は、どちらかを入り口にして他方を参照するようにする
  • @ContextConfigurationのinheritLocations(デフォルトtrue)をtrueにすると、親クラスのlocationsとclasses属性を引き継いて、それに追加できるようになる。
  • @ContextConfigurationのinheritLocationsをfalseにすると、親クラスのlocationsとclasses属性は認識されない

ビーン定義プロファイル

  • 3.1から(SmartContextLoader SPIを利用した場合に有効)
  • テスト環境ごとに利用するビーン定義を切り替えられる
  • テストクラスに@ActiveProfilesをつける
  • 切り替えたいビーン定義には、
     <beans profile="xxx"> for XMLビーン定義
     @ActiveProfiles("xxx") for コンフィグレーションクラス
    

コンテキストキャッシュ

  • テストスィート上でApplicationContextは以下の組み合わせのキーでキャッシュされる
    locations (from @ContextConfiguration)
    classes (from @ContextConfiguration)
    contextLoader (from @ContextConfiguration)
    activeProfiles (from @ActiveProfiles)
    
  • キャッシュを使うには、1テストスィート上で全てのテストを実行できるようにする
  • ビルドフレームワークのテスト実行のフォークを確認
  • @DirtiesContextが付けられたテストの実行後にはコンテキストはリロードされる

テストクラスへのDI

  • DependencyInjectionTestExecutionListenerでDIが可能になる
  • setter、フィールドインジェクション両方可能
  • @Autowiredは型解決
    • 同じかたのビーンが2つ以上あるときは、@Qualifierと一緒に
    • @Qualifierは<bean>の中の<qualifier>の値と一致するもの、またはフォールバックとしてビーン名と一致するものを指定
    • @Inject + @Namedでも可能
    • DIを完全に無効にしたければテストクラスの@TestExecutionListenersで、DependencyInjectionTestExecutionListenerを省く

トランザクション管理

  • TransactionalTestExecutionListenerによって実現される(デフォルトで有効になってる)
    • PlatformTransactionManagerは自前で定義
  • @Transactionalをテストクラス/メソッドに
  • @Rollbackをテストメソッドに
  • @TransactionConfigurationでクラスレベルのトランザクションの設定
  • トランザクションを使うテストの抽象⇒AbstractTransactionalJUnit4SpringContextTests
  • トランザクションの開始前の処理:@BeforeTransaction
    • DBの初期状態の確認とか
    • @Beforeメソッドはトランザクション開始後に実行される
  • トランザクションの終了後の処理:@BeforeTransaction
    • コミットを伴うテストで事後の確認とか
    • @Afterメソッドはトランザクション終了前に実行される
  • O/Rマッパでメモリにキャッシュする場合は、テストメソッドの中にちゃんとflushも含める

サポートクラス

  • JUnit4サポート
    • AbstractJUnit4SpringContextTests
      • ApplicationContextへのアクセス
    • AbstractTransactionalJUnit4SpringContextTests
      • トランザクションサポート
      • ApplicationContextへのアクセス
      • simpleJdbcTemplateへのアクセス
      • 便利なメソッド
  • Spring JUnit Runner
    • テストクラスにつける
      @RunWith(SpringJUnit4ClassRunner.class)
      

テストコンテキスト戦略

  • できるだけ、本番用のビーン定義と結合テストビーン定義は同じにする
  • DBのコネクションプールとかトランザクション管理のビーン定義は別に分ける
  • 接続文字列とかはプロパティファイルに外だしする
最終更新:2012年02月27日 15:39
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。