#概要
JavaEEのテストをJavaEEのテスティングフレームワークであるArquillianで実施してみます。
CDIとinterceptorがJavaEEサーバを用意せずともローカルで動かすことができるので、便利です。
今回使用したソースはGithubにUPしています。
https://github.com/tuto00/Arquillian
#対象読者
JavaEEのテスト初心者
#準備
##Maven
Mavenを使用するため、pom.xmlを編集します。
JavaEE、Junit、Arquillianのライブラリの依存関係を追加します。
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-7.0</artifactId>
<version>1.0.3.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.4.0.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>1.4.0.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
<version>1.0.0.CR9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>2.3.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
</dependencies>
##beans.xml
interceptorを使用したいため用意してください。
<?xml version="1.0" ?>
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1"
bean-discovery-mode="all">
<interceptors>
<class>org.arquillian.interceptor.TraceInterceptor</class>
</interceptors>
</beans>
#実装
GreetServiceクラスにHelloクラスをInjectします。
また、GreetServiceクラスにInterceptor(SampleInterceptor)を適用し、メソッド実行前後でログ出力を行います。
@Named
@ApplicationScoped
@SampleInterceptor
public class GreetService {
@Inject
Hello hello;
public String greet(){
return hello.hello();
}
}
Helloクラスにも@ApplicationScopedを付与してCDI管理Beanにしています。
@ApplicationScoped
public class Hello {
public String hello() {
return "helloWorld";
}
}
次に、Interceptorを特定し、実行するためのアノテーションを作成します。
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface SampleInterceptor {
}
そして、上記で作成したSampleInterceptorを実装する形で以下を準備します。
メソッド実行前にクラス名、メソッド名を出力するようにしています。
@Interceptor
@SampleInterceptor
public class TestInterceptor {
@AroundInvoke
public Object obj(InvocationContext ic) throws Exception {
// メソッド実行前
System.out.println("process start class :" + ic.getTarget().getClass().getSimpleName()
+ " method:" + ic.getMethod().getName());
// メソッド実行
Object result = ic.proceed();
// メソッドの実行後
System.out.println("process end");
return result;
}
}
#テストコード
やっと本題のArquillianを使用します。
テストコードを書いていきます。
@RunWith(Arquillian.class)
public class GreetServiceTest {
@Inject
GreetService greeter;
@Deployment
public static JavaArchive createDeployment() {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
.addPackage("org.arquillian.example")
.addPackage("org.arquillian.annotation")
.addPackage("org.arquillian.interceptor")
.addAsManifestResource(new File("src/main/webapp/WEB-INF/beans.xml"));
System.out.println(jar.toString(true));
return jar;
}
@Test
public void should_create_greeting() {
assertEquals("helloWorld", greeter.greet());
}
}
通常のJunitとは異なりArquillianを使用するときのポイントは2つあります。
- テストクラスに@RunWith(Arquillian.class)を付与します。
- @Deploymentを付与したアーカイブ作成メソッドを作成します。
動きとしては以下となります。
@RunWith アノテーションは、JUnitに、Arquillianをテストコントローラとして使用することを伝えます。Arquillianはテストアーカイブ(つまり、マイクロデプロイメント)を受け取るために @Deployment アノテーションのついたパブリックなスタティックメソッドを探します。そしてマジックが起きて、それぞれの @Test メソッドはコンテナ環境内で実行されます。
要は、jarを作成して、コンテナで実行しているということですね。
コンテナについては、Arquillianのコンテナアダプタがコントロールしています。
今回はコンテナとしてWeldを使用し、コンテナアダプタとしてarquillian-weld-ee-embedded-1.1を使用しています。
#テスト実行
さあ、テストを実行してみましょう。
通常のJunitと同じく、テストクラスをJunit実行すればよいです。
テスト結果がグリーンになり、コンソールに以下が出力していることを確認してください。
588b9820-a6f0-4ffe-b6bd-e8228bc24b98.jar:
/org/
/org/arquillian/
/org/arquillian/example/
/org/arquillian/example/Hello.class
/org/arquillian/example/GreetService.class
/org/arquillian/example/GreeterTest.class
/org/arquillian/annotation/
/org/arquillian/annotation/SampleInterceptor.class
/org/arquillian/interceptor/
/org/arquillian/interceptor/TraceInterceptor.class
/META-INF/
/META-INF/beans.xml
INFO: WELD-000900: 2.3.5 (Final) [日 6 23 18:06:32 JST 2019]
process start class :GreetService$Proxy$_$$_WeldSubclass method:greet
process end
process start、process endとinterceptorが適用されていることがわかります。
#おわりに
Arquillianを使用すると、CDIやintercptorを簡単にテストすることができます。
みなさんも使ってみてください。
難点としては、ドキュメントが少ないことです。。。
#参考URL
Arquillian Guides