前回までで、ManagedモードでArquillianを使ったEJBとJAX-RSのテストをやってみたので、今回はRemoteモードを使ってみます。
今回の対象は、EJBとJAX-RSリソースとして作成したクラスとします。
依存関係の定義とテスト対象
依存関係の定義。
build.sbt
name := "arquillian-remote" version := "0.0.1-SNAPSHOT" scalaVersion := "2.10.3" organization := "littlewings" resolvers += "Public JBoss Group" at "http://repository.jboss.org/nexus/content/groups/public-jboss" fork in Test := true libraryDependencies ++= Seq( "org.jboss.spec" % "jboss-javaee-web-6.0" % "3.0.2.Final" % "provided", "org.jboss.as" % "jboss-as-arquillian-container-remote" % "7.1.1.Final" % "test" excludeAll( ExclusionRule(organization = "org.jboss.shrinkwrap"), ExclusionRule(organization = "org.jboss.shrinkwrap.descriptors") ), "org.jboss.arquillian.junit" % "arquillian-junit-container" % "1.1.2.Final" % "test" excludeAll( ExclusionRule(organization = "org.jboss.shrinkwrap"), ExclusionRule(organization = "org.jboss.shrinkwrap.descriptors") ), "org.jboss.arquillian.protocol" % "arquillian-protocol-servlet" % "1.1.2.Final" % "test", "org.jboss.shrinkwrap" % "shrinkwrap-api" % "1.0.0-cr-1" % "test", "org.jboss.shrinkwrap" % "shrinkwrap-impl-base" % "1.1.2" % "test", "org.jboss.shrinkwrap.descriptors" % "shrinkwrap-descriptors-spi" % "2.0.0-alpha-3" % "test", "org.jboss.shrinkwrap.resolver" % "shrinkwrap-resolver-depchain" % "2.0.1" % "test" excludeAll( ExclusionRule(organization = "org.jboss.shrinkwrap") ), "org.jboss.resteasy" % "resteasy-jaxrs" % "2.3.2.Final" % "test", "junit" % "junit" % "4.11" % "test", "com.novocode" % "junit-interface" % "0.10" % "test" )
sbtを使った場合のShrinkWrapの依存関係での注意点は、Managedモードと同じでした。
"org.jboss.arquillian.protocol" % "arquillian-protocol-servlet" % "1.1.2.Final" % "test",
テスト対象となるクラスは、簡単なものにしておきます。まずはEJB。
src/main/scala/javaee6/web/service/CalcService.scala
package javaee6.web.service import javax.ejb.{LocalBean, Stateless} @Stateless @LocalBean class CalcService { def add(left: Int, right: Int): Int = left + right def multiply(left: Int, right: Int): Int = left * right }
JAX-RSの有効化。
src/main/scala/javaee6/web/rest/JaxrsApplication.scala
package javaee6.web.rest import javax.ws.rs.ApplicationPath import javax.ws.rs.core.Application @ApplicationPath("/rest") class JaxrsApplication extends Application
Scalaを使った場合、メソッドとか定義しないんなら、波括弧って要らないの忘れてました…。
JAX-RSリソースクラス。
src/main/scala/javaee6/web/rest/CalcResource.scala
package javaee6.web.rest import javax.enterprise.context.RequestScoped import javax.ws.rs.{GET, Path, Produces, QueryParam} import javax.ws.rs.core.MediaType @RequestScoped @Path("calc") class CalcResource { @GET @Path("add") @Produces(Array(MediaType.TEXT_PLAIN)) def add(@QueryParam("p1") p1: Int, @QueryParam("p2") p2: Int): String = (p1 + p2).toString }
CDIも、一応有効化しておきます。
src/main/webapp/WEB-INF/beans.xml
テストコード
Arquillianの設定。デフォルトプロトコルを、Servlet 3.0に。
src/test/resources/arquillian.xml
<?xml version="1.0" encoding="UTF-8"?> <arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> <defaultProtocol type="Servlet 3.0"/> </arquillian>
Maven使ってないから、profileの切り替え方がわかりません!今回は困りませんけど。
EJBのテスト。
src/test/scala/javaee6/web/service/CalcServiceTest.scala
package javaee6.web.service import javax.ejb.EJB import javax.inject.Inject import org.jboss.arquillian.container.test.api.Deployment import org.jboss.arquillian.junit.Arquillian import org.jboss.shrinkwrap.api.ShrinkWrap import org.jboss.shrinkwrap.api.asset.EmptyAsset import org.jboss.shrinkwrap.api.spec.WebArchive import org.jboss.shrinkwrap.resolver.api.maven.Maven import org.junit.Test import org.junit.runner.RunWith import org.junit.Assert._ import org.hamcrest.CoreMatchers._ @RunWith(classOf[Arquillian]) class CalcServiceTest { // CDIを使わず、LocalBeanとする場合はJNDI名が必要らしい //@EJB(mappedName = "java:global/arquillian-test/CalcService") @Inject private var calcService: CalcService = _ @Test def addTest: Unit = assertThat(calcService.add(1, 2), is(3)) @Test def multiplyTest: Unit = assertThat(calcService.multiply(2, 3), is(6)) } object CalcServiceTest { @Deployment def createDeployment: WebArchive = ShrinkWrap .create(classOf[WebArchive], "arquillian-test.war") .addPackages(true, "javaee6.web.service") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsLibraries { Maven .resolver .resolve("org.scala-lang:scala-library:2.10.3") .withTransitivity .asFile: _* } }
ちょっとハマったのは、ここでした。
// CDIを使わず、LocalBeanとする場合はJNDI名が必要らしい //@EJB(mappedName = "java:global/arquillian-test/CalcService") @Inject private var calcService: CalcService = _
前回、ManagedモードでEJBのテストをした時は@Injectアノテーションでテストしていたのですが、軽い気持ちで@EJBアノテーションを試してみたら、見事にハマりました。
ローカルBeanを使う時は、JNDIルックアップ名を指定する必要があるみたいです…。
Explicite Local EJB not injected with Arquillian
http://stackoverflow.com/questions/10089957/explicite-local-ejb-not-injected-with-arquillian
もしくは、CDIを使う場合はbeans.xmlをデプロイするようにします。
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
続いて、JAX-RSのテスト。
src/test/scala/javaee6/web/rest/CalcResourceTest.scala
package javaee6.web.rest import java.io.File import java.net.URL import javax.ws.rs.ApplicationPath import javax.ws.rs.core.{MediaType, Response} import org.jboss.arquillian.container.test.api.{Deployment, RunAsClient} import org.jboss.arquillian.junit.Arquillian import org.jboss.arquillian.test.api.ArquillianResource import org.jboss.resteasy.client.ClientRequest import org.jboss.shrinkwrap.api.ShrinkWrap import org.jboss.shrinkwrap.api.asset.EmptyAsset import org.jboss.shrinkwrap.api.spec.WebArchive import org.jboss.shrinkwrap.resolver.api.maven.Maven import org.junit.Test import org.junit.runner.RunWith import org.junit.Assert._ import org.hamcrest.CoreMatchers._ @RunWith(classOf[Arquillian]) @RunAsClient class CalcResourceTest { private val resourcePrefix = classOf[JaxrsApplication] .getAnnotation(classOf[ApplicationPath]) .value .substring(1) @ArquillianResource private var deploymentUrl: URL = _ @Test def calcTest: Unit = { val request = new ClientRequest(s"${deploymentUrl}${resourcePrefix}/calc/add?p1=3&p2=4") request.header("Accept", MediaType.TEXT_PLAIN) val response = request.get(classOf[String]) assertThat(response.getStatus, is(Response.Status.OK.getStatusCode)) assertThat(response.getEntity, is("7")) } } object CalcResourceTest { @Deployment def createDeployment: WebArchive = ShrinkWrap .create(classOf[WebArchive], "arquillian-test.war") .addPackages(true, "javaee6.web.rest") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsLibraries { Maven .resolver .resolve("org.scala-lang:scala-library:2.10.3") .withTransitivity .asFile: _* } }
実はいろいろハマったのですが、コピペミスとかそういうくだらないことでした…。
で、テストのやり方なのですが、どうやればいいのかがわからず、とりあえずJBoss ASを起動して
jboss-as-7.1.1.Final/bin/standalone.sh
テストを実行したら、普通に認識してくれました…。
> test
確かに、Managedモードでやるより高速ですね。
一応、JMXでも問題なく実行できました。
とりあえず、Arquillianの普通の使い方はひとめぐりしました?的な。
今回のソースは、こちらにアップしています。
https://github.com/kazuhira-r/javaee6-scala-examples/tree/master/arquillian-remote