Java EE7和Maven工程入门(5),ee7maven
Java EE7和Maven工程入门(5),ee7maven
目录
- 一个简单Maven工程的结构
- 建立一个简单的WAR工程
- 定义ejb services模块和jpa实体模块
- 定义EAR模块
- 使用Arquillian进行单元测试(上)
- 使用Arquillian进行单元测试(下)
- 使用PostagreSQL与ShrinkWrap API进行测试
这是第一个“番外篇”,基于为Maven JavaEE7系列博客 “搭建”的演示项目。我们已经定义了一个坚实的基础结构和一些模块。在应用程序中,一般使用Arquillian(+JUnit)这个完美的框架。在进行单元测试和EJB服务时我们能够使用“真实”的应用服务,这个服务几乎与将要部署的服务一模一样。实际上,我看了一些在这里找到的基础设置指南。与指南不同,我将使用Wildfly 8.1 作为单元测试的嵌入式容器。Wildfly 8.1是一个十分成熟的JavaEE7容器,使我能够安全地测试所有特性。
Arquillian思想和Maven
为了在Maven化项目中使用Arquillian,你需要了解最基本的事情就是遵循以下术语(概念)。这些概念会被定义为各种依赖:
- 你需要Arquillian框架、库。想象一下,一台新的轿车却没有发动机,那么前面的工作都是无意义的。
- 你需要Arquillian容器适配器(Container Adapter)。设想你需要在你的车前安装占位装置(placeholder),比如框架以便发动机能够安装其中。
- 你需要真正的容器(应用程序服务器)。这就是我们将要安装适合我们汽车的发动机(engine)。
- 你需要JUnit。这就是你的汽车将要被测试所跑的“测试跑道(Test Track)”。
- 你需要代码(EJBs)。这些就是你将要被测试的汽车所要搭载的乘客。
定义父pom的依赖关系
正如我们在前面四篇文章中描述的,父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类型和import域(import scope)。实际上,这是在定义一组依赖中的特例。pom类型的依赖,意思是说这是由一组独立库组合而成的。只需要定义这个超级pom,就会继承这些包含其中的各个依赖。在Maven术语中,这样一组依赖被称为BOM或材料清单(Bill of Materials)。Arquillian由若干具体的库和依赖构成,不用逐个义。而使用arquillian-pom定义能够达到同样的效果。
- “arquillian-transaction-bom”是可选依赖,可以不定义。它在测试中可以增加额外的特性,这其中最有名的就是@Transactional arquillian注解。可以在这里或这里here查更多信息。
- Wildfly和JBoss是例外,需要使用“wildfly-embedded”标记依赖。假设这是个Wildfly应用服务器“嵌入的(embedded)”Uber jar版本,Glassfish就是如此。最后,这是人们尝试在Wildfly中安装Arquillian常见的错误。为了使整个工作运转,你需要下载“真实的”应用服务器。请继续看下面部分,会有助于解决这个特殊问题。
(译注,Uber Jar在一个Jar中包含了你的Jar包及所有依赖。关于Uber Jar请参见这里)
为我们的EJB模块配置Arquillian和测试
在示例程序中,我们已经在名为sample-ejb的模块中编写了大部分EJB服务,因此我们需要为pom添加额外的配置工作,以便于在模块测试中使用junit+Arquillian。
这个pom的绝大部分的配置工作,是为了适应Wildfly的特殊情况。为了在测试阶段使所有机制正常运转,需要下载Wildfly.zip(可以从浏览器下载),解压到某个位置,并指定Arquillian路径。一旦完成,Arquillian将会接管所有工作。
首先,下载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。
- 我们指明plugin在Maven生命周期的process-test-classes阶段生效。当开始生效时,去执行“unpack”目标(goal)。因此,在Maven启动之前,运行上面的测试会下载并解压Wildfly 8.1到classpath。
使用maven-surfire插件运行测试
下面代码是sample-services.pom的一部分。配置了Maven Serefire Plugin,该插件实际执行JUnit-Arquillian测试。
<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是一个特殊情况,容器将会被下载到输出或目标文件夹。
在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()); } }
完成
在sample-parent文件夹下,输入:
mvn clean packege
完整示例可以在这里下载。
原文链接: javacodegeeks 翻译: Wld5.com - lomoxy译文链接: http://www.wld5.com/13573.html
[ 转载请保留原文出处、译者和译文链接。]
用户点评