从前面的部分恢复
第1 部分 , 第2 部分 , 第3 部分 , 第4部分 ,
这是第一篇“额外”的帖子,基于我正在此系列博客文章上“构建”的Maven JavaEE7演示项目。 我们已经定义了一个坚实的结构和一些模块。 在这样的应用程序中,一个非常常见的情况是使用Arquillian (+ JUnit ),这是一个上帝赐予的框架,它使我们能够使用“真实的”应用程序服务器对EJB服务进行单元测试,最有可能与我们将要使用的相同。部署到。 我实际上遵循的是这里的基本设置指南,不同之处在于,我将Wildfly 8.1设置为嵌入式容器来承载单元测试。 Widlfy 8.1是一个功能强大的JavvaEE7容器,因此我可以安全地测试所有功能。
Arquillian心态和Maven
为了在Maven化的项目中采用Arquillian,您需要了解的基本知识之一是以下实际上作为依赖项实现的术语(思想)。
- 当然,您需要Arquillian框架/库,想象一下这是一辆新车,但缺少它的引擎。 前部是空的。
- 您需要一个Arquillian Container Adapter ,假设您需要在汽车的前部安装某种占位符 ,例如将要使用的框架,以便可以“安装”发动机。
- 您需要一个真正的容器(应用程序服务器),这是我们要安装在汽车中的引擎 。
- 您需要JUnit ,这是您的汽车将要运行并进行测试的“ 测试 轨道 ”。
- 您需要您的代码(您的EJB),这些代码将被放置在汽车中并在Junit轨道上测试行程的乘客。
定义对父pom的依赖
正如我们在前4个帖子中已经详细说明的那样,父pom是定义要在我们的应用程序中使用的依赖项及其库版本的地方。 请记住上面的术语列表,让我们开始并更新父pom的dependencyManagement部分。
<junit-version>4.11</junit-version>
<arquillian-version>1.1.4.Final</arquillian-version>
<arquillian-wildfly-version>8.1.0.CR2</arquillian-wildfly-version>
<arquillian-transaction-version>1.0.1.Final</arquillian-transaction-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api-version}</version>
</dependency>
<!-- -JUNIT-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
</dependency>
<!-- rquillian itself-->
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${arquillian-version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!-- this is in an extention to arquillian it is optional-->
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-transaction-bom</artifactId>
<version>${arquillian-transaction-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- this is container adapter for wildfly-->
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>${arquillian-wildfly-version}</version>
</dependency>
<!-- this is the wildfly emb.container - BUT eventually it is not a fully blown emb.container-->
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>${arquillian-wildfly-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
有关上述片段的一些技巧:
- 一些依赖项是pom类型和作用域导入。 实际上,这是一起定义依赖项组的一种特殊情况。 pom类型依赖性表示这是在此定义下分组在一起的一组单个库。 您只需要定义该超级pom,您将继承其中的各个依赖项。 在Maven术语中,这种依赖性分组称为“ BOM ”或也称为“ 物料清单 ”。 Arquillian由几个具体的库和依赖项组成,而不是一个一个地定义每个库,如果定义arquillian-bom,则结果相同。
- “ arquillian-transaction-bom ”是一个可选的依赖项,您可以不定义它,它为Arquillian引擎和您的测试中添加了额外的功能。 最著名的“额外”功能之一是“ @Transactional” arquillian注释。 在此处或此处查看详细信息。
- Wildfly和JBoss的特殊情况。 您会注意到依赖项“ wildfly-embedded ”,并假设它是Wildfly应用程序服务器的“ 嵌入式 ” uber jar版本,例如Glassfish的版本。 最终不是这样,这是人们在尝试使用Wildfly设置Arquillian时常犯的错误。 为了使整个工作正常进行,您需要下载“真实的”应用程序服务器。 请看以下部分,将在哪里解决这个特殊情况。
为Arquillian和测试配置我们的ejb模块
在演示应用程序中,我们已将大多数EJB服务“编码”在名为sample-ejb的模块上。 因此,我们需要在其pom中添加额外的配置,以便在该模块的测试阶段“ 触发 ” junit + arquillian测试。
大多数配置将在此pom上执行,以覆盖Widlfly的这种“ 特殊 ”情况,即未作为完全吹入的嵌入式容器提供。 因此,为了使整个机制正常工作,我们需要在测试阶段告诉Maven,下载Wildfly.zip(例如,使用浏览器进行此操作),将其解压缩到某个地方,然后将Arquillian指向路径。 完成后,rAquillian将接任。
事先下载wildfly服务器
下面的配置写在sample-services pom(我们的“ EJB服务”模块)中:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-dist</artifactId>
<version>8.1.0.Final</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
有关上述片段的一些技巧:
- 我们使用maven-dependency-plugin
- 我们指示插件在Maven生命周期的“过程测试类”阶段启动,以及在执行“解压”目标时启动。 因此,在Maven开始运行测试之前,配置的上述部分将已将Wildfly 8.1下载并解压缩到类路径中。
使用maven运行测试– surfire插件
同样,下面的代码是sample-services.pom的一部分。 我们实际上配置了Maven Surefire插件,它是执行Junit-Arquilian测试的插件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Fork every test because it will launch a separate AS instance -->
<forkMode>always</forkMode>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<jboss.home>${project.basedir}/target/wildfly-8.1.0.Final</jboss.home>
<module.path>${project.basedir}/target/wildfly-8.1.0.Final/modules</module.path>
</systemPropertyVariables>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
/configuration>
</plugin>
有关上述片段的一些技巧:
- Surefire为单元测试提供了执行环境。 在我们的案例中,我们有Junit-Arquillian进行的测试。 为了使Arquillian正确地初始化自身并标识容器,我们需要将其作为系统参数传递给下载应用程序服务器的路径。 请记住,wildfly / jboss是一个特例。 该容器将已经下载到/ target文件夹中。
在sample-services模块上添加所需的依赖项
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<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-embedded</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-transaction-jta</artifactId>
<scope>test</scope>
</dependency>
创建样本测试
package gr.javapapo;
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.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.ejb.EJB;
/**
* Created by papo on 5/31/14.
*/
@RunWith(Arquillian.class)
public class DemoArquillianTest {
@EJB
UserServices dummyService;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(UserServices.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void testSaysHello() {
Assert.assertEquals("hello",dummyService.sayHello());
}
}
我们完了
在样本父文件夹级别下,键入:
mvn clean package
- 该示例的完整代码可在以下bitbucket标签上找到。