1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ArquillianでJavaEEテスト(CDI・interceptor)

Posted at

#概要
JavaEEのテストをJavaEEのテスティングフレームワークであるArquillianで実施してみます。
CDIとinterceptorがJavaEEサーバを用意せずともローカルで動かすことができるので、便利です。

今回使用したソースはGithubにUPしています。
https://github.com/tuto00/Arquillian

#対象読者
JavaEEのテスト初心者

#準備
##Maven
Mavenを使用するため、pom.xmlを編集します。
JavaEE、Junit、Arquillianのライブラリの依存関係を追加します。

pom.xml
	<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を使用したいため用意してください。

beans.xml
<?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)を適用し、メソッド実行前後でログ出力を行います。

GreetService.java
@Named
@ApplicationScoped
@SampleInterceptor
public class GreetService {

	@Inject
	Hello hello;

    public String greet(){
    	return hello.hello();
    }
}

 
Helloクラスにも@ApplicationScopedを付与してCDI管理Beanにしています。

Hello.java
@ApplicationScoped
public class Hello {

	public String hello() {
		return "helloWorld";
	}
}

次に、Interceptorを特定し、実行するためのアノテーションを作成します。

SampleInterceptor.java
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface SampleInterceptor {
}

そして、上記で作成したSampleInterceptorを実装する形で以下を準備します。
メソッド実行前にクラス名、メソッド名を出力するようにしています。

TraceInterceptor.java
@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を使用します。
テストコードを書いていきます。

GreetServiceTest.java
@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

1
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?