Kohei Nozaki's blog 

Arquillian用ArchiveへクラスとMaven Dependencyを楽に追加する


Posted on Tuesday Jan 28, 2014 at 09:48PM in Technology


環境

  • shrinkwrap-resolver 2.1.0-alpha-1
  • wildfly-arquillian-container-remote 8.0.0.CR1
  • Arquillian 1.1.2.Final
  • WildFly 8.0.0.CR1
  • Eclipse Kepler SR1
  • Oracle JDK7u51

サブパッケージを再帰的に探索させてクラスを追加する

例えばこういう状況で

テストするのに必要なクラス群が複数のパッケージに分散している

クラスの配置

Hige.java

package org.example.hige;

import javax.inject.Named;

@Named
public class Hige {

    public String hige() {
        return "hige()";
    }
}

Hoge.java

package org.example.hoge;

import javax.inject.Inject;
import javax.inject.Named;

import org.example.hige.Hige;

@Named
public class Hoge {

    @Inject
    Hige hige;

    public String hoge() {
        return "hoge()" + hige.hige();
    }
}

こうするとよい

Archive作成時にaddPackages()メソッドをこういう感じで呼んでやればよい。これでいちいち全パッケージに対してaddPackage()呼んでやらずにすむ。第一引数がtrueだと、第二引数で与えたパッケージのサブパッケージを再帰的に探索してくれる。

テストクラス

package org.example.hoge;

import javax.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class HogeTest {

    @Deployment
    public static Archive<?> createDeployment() {
        WebArchive a =
                ShrinkWrap.create(WebArchive.class, "test.war")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
                .addPackages(true, "org.example");
        return a;
    }

    @Inject
    Hoge hoge;

    @Test
    public void test() throws Exception {
        Assert.assertEquals("hoge()hige()", hoge.hoge());
    }
}

Maven Dependencyを楽に追加する

例えばこういう状況で

guavaをpom.xmlに設定して使っている。Archiveを作る際に、いちいち依存するjarファイルをaddLibraryしていくのが面倒くさい。

Hoge.java

package org.example.hoge;

import javax.inject.Named;

import com.google.common.collect.Lists;

@Named
public class Hoge {

    public void hoge() {
        Lists.newArrayList();
    }
}

こうするとよい

pom.xml

shrinkwrap-resolverへの依存を追加する(groupIdがorg.jboss.shrinkwrap.resolverの要素)。例えばこんな感じ

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>arquillian-prac</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.shrinkwrap.resolver</groupId>
                <artifactId>shrinkwrap-resolver-bom</artifactId>
                <version>2.1.0-alpha-1</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.1.2.Final</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.9.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-integration</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>net.avh4.util</groupId>
            <artifactId>imagecomparison</artifactId>
            <version>0.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.wildfly</groupId>
            <artifactId>wildfly-arquillian-container-remote</artifactId>
            <version>8.0.0.CR1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.extension</groupId>
            <artifactId>arquillian-persistence-impl</artifactId>
            <version>1.0.0.Alpha6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.shrinkwrap.resolver</groupId>
            <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
            <version>2.1.0-alpha-1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.shrinkwrap.resolver</groupId>
            <artifactId>shrinkwrap-resolver-api-maven</artifactId>
            <version>2.1.0-alpha-1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>16.0</version>
        </dependency>
    </dependencies>
</project>

テストクラス

package org.example.hoge;

import javax.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
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.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class HogeTest {

    @Deployment
    public static Archive<?> createDeployment() {
        WebArchive a =
                ShrinkWrap.create(WebArchive.class, "test.war")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
                .addPackages(true, "org.example");

        a.addAsLibraries(
                Maven.resolver()
                .loadPomFromFile("pom.xml")
                .importRuntimeDependencies()
                .resolve()
                .withTransitivity()
                .asFile());

        return a;
    }

    @Inject
    Hoge hoge;

    @Test
    public void test() throws Exception {
        hoge.hoge();
        Assert.assertTrue(true);
    }
}

importRuntimeDependencies()の他にもいろいろあるので必要に応じて使い分ける。ただ多くなりすぎるとデプロイが遅くなる。

  • importRuntimeAndCompileDependencies()
  • importDependencies(ScopeType…)
  • importRuntimeAndTestDependencies()
  • importRuntimeDependencies()
  • importTestDependencies()

こういう感じにすると依存性を個別に追加できる[3]

        File[] files = Maven.resolver()
                .loadPomFromFile("pom.xml")
                .resolve("org.apache.commons:commons-lang3:3.2.1")
                .withTransitivity()
                .asFile();

        WebArchive w = ShrinkWrap.create(WebArchive.class, "hoge.war").addClass(HogeBean.class)
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml").addAsLibraries(files);

バージョンの省略も可。省略するとpom.xmlに書いてあるバージョンを取ってきてくれる

        File[] files = Maven.resolver()
                .loadPomFromFile("pom.xml")
                .resolve("org.apache.commons:commons-lang3")
                .withTransitivity()
                .asFile();

参考文献

  1. Add all classes in src/main/java | Community
  2. java - Adding all Maven dependencies to Arquillian - Stack Overflow
  3. shrinkwrap/resolver · GitHub
  4. Using the ShrinkWrap Maven Resolver for Arquillian Tests | Develop In Java
  5. arquillian 1.1.0 final and shrinkwrap | Community
  6. Add directory recursively to arquillian using S… | Community
  7. Add src/main/java to webarchive | Community



No one has commented yet.

Leave a Comment

HTML Syntax: NOT allowed