ホワイトプログラマー

40歳からSEを辞めてプログラマになりました

Arquillianを使用したJavaEE7のユニットテスト(サンプル実装付き)

JavaEE7での単体テストと課題

Strutsなどのフレームワークにおいてはフレームワークと業務ロジックの実装が密結合であったため、単体テストが難しいと言われていた。それに比べてJavaEE7はCDI自体がPOJOであるため単体テストは容易であると喧伝されている。
果たしてそうなのか。たしかに、メソッドの単体テストやUtilをテストするにはJUnitとMockitがあればある程度記述できる。しかし、Injectされたオブジェクトを全てMockで書き始めると段々と、単体テストの意義が小さくなってくることに気づく。
大きなプロジェクトでは発注者は単体テストのコードや仕様をレビューせず、カバレッジしか気にしないことが多い。これもあって、SIerが開発するJavaEEのテストコードは動くコードができてから、それに対してMockだらけのテストコードを書くだけという結果が多く見られる。
最初からそのプロジェクトにおいて意味のあるテストコードが何なのかが議論できていないことからこの問題が発生する。

テストの対象を切り分ける

JavaEE7でもBeanValidationのテストはEnclosedやTheoryなどを使うことで、十分にテストの実施が可能である。ただ、悩ましいのはテスト対象のオブジェクトがInjectしているオブジェクトに対してどこまで実施するかだ。これはプロジェクトで事前に決めることが大事となる。

切り分けの範囲

何をまず決めるかというと、JavaEE7のコンテナ上で動かすテストとそれ以外である。 MVCS with DAOのよくあるパターンでアプリケーションを作成した場合に、コンテナを使用したテストであるArquillianをどのように利用するかを図解してみた。

f:id:sabburo:20161226114746j:plain

1.Serviceより下の層をArquillianを使用してテストする
    JUnit + mockit + Arquillian
2.Controllerより下の層をArquillianを使用してテストする
    JUnit + mockit + Arquillian + Drone
3.Controllerより下の層をArquillianを使用してテストする(ViewScopedも含める)
    JUnit + mockit + Arquillian + Drone + warp

サンプル実装として、1のサンプル実装を以下に紹介する。 Arquillianを使用する際は、@Deploymentの部分をどのように実装するかがポイントになるがサンプルでは、クラス、xhtml、pomで定義した依存ライブラリの全てをパッケージングする定義としている。

Arquillianを使用したUnitTestコード

参考URL

ArquillianでViewScopedのCDI管理BeanだけInjectできない - Challenge Java EE !

Arquillian用ArchiveへクラスとMaven Dependencyを楽に追加する - Kohei Nozaki's blog

Functional Testing using Drone and Graphene · Arquillian Guides

java - deploymentURL not injected into integration test with Arquillian Drone - Stack Overflow