ejb+jpa_使用Arquillian(包括JPA,EJB,Bean验证和CDI)测试Java EE 6
ejb+jpa
很長(zhǎng)時(shí)間以來(lái),我聽(tīng)到很多人對(duì)Arquillian說(shuō)好話 。 盡管我一直在閱讀有關(guān)其用法的文章,但實(shí)際上我無(wú)法在一篇文章中找到涵蓋我認(rèn)為重要的某些方面的文章。 當(dāng)然,我看起來(lái)還不夠努力。
我要講的要點(diǎn)是:
- 使用JPA。 我只是在這里使用EclipseLink,
- 使用內(nèi)存數(shù)據(jù)庫(kù)
- 使用CDI注射,
- EJB的使用,例如本地?zé)o狀態(tài)會(huì)話Bean,
- 使用JSR-303 Bean驗(yàn)證,
- 使用(嵌入式)玻璃魚(yú)進(jìn)行集成測(cè)試。
我花了一些時(shí)間來(lái)收集信息以啟動(dòng)并運(yùn)行該項(xiàng)目。 我以為我專門寫(xiě)這篇文章來(lái)幫助那些有類似要求的人。 那么,我們還在等什么! 開(kāi)始吧!!!
配置pom.xml
當(dāng)然,我們需要配置項(xiàng)目以使用Arquillian,還需要使用EclipseLink作為持久性提供程序。 但是,請(qǐng)記住,在決定使用內(nèi)存數(shù)據(jù)庫(kù)之前,我們也要做出決定。 您可能希望在此pom.xml中包括您的依賴項(xiàng)。 但是,我決定使用Derby,它在標(biāo)準(zhǔn)Oracle Java SDK類路徑中可用。
無(wú)論如何,所以pom.xml看起來(lái)像這樣:
<?xml version="1.0" encoding="UTF-8"?> <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><parent><artifactId>inout</artifactId><groupId>id.co.dwuysan</groupId><version>1.0-SNAPSHOT</version></parent><groupId>id.co.dwuysan</groupId><artifactId>inout-ejb</artifactId><version>1.0-SNAPSHOT</version><packaging>ejb</packaging><name>inout-ejb</name><properties><endorsed.dir>${project.build.directory}/endorsed</endorsed.dir><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server></properties><dependencyManagement><dependencies><dependency><groupId>org.jboss.arquillian</groupId><artifactId>arquillian-bom</artifactId><version>1.0.0.Final</version><scope>import</scope><type>pom</type></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.eclipse.persistence</groupId><artifactId>eclipselink</artifactId><version>2.3.2</version><scope>provided</scope></dependency><dependency><groupId>org.eclipse.persistence</groupId><artifactId>javax.persistence</artifactId><version>2.0.3</version><scope>provided</scope></dependency><dependency><groupId>org.eclipse.persistence</groupId><artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId><version>2.3.2</version><scope>provided</scope></dependency><!-- test --><dependency><groupId>org.jboss.arquillian</groupId><artifactId>arquillian-bom</artifactId><version>1.0.3.Final</version><type>pom</type></dependency><dependency><groupId>org.glassfish.main.extras</groupId><artifactId>glassfish-embedded-all</artifactId><version>3.1.2.2</version><scope>provided</scope></dependency><dependency><groupId>org.jboss.arquillian.container</groupId><artifactId>arquillian-glassfish-embedded-3.1</artifactId><version>1.0.0.CR3</version><scope>test</scope></dependency><dependency><groupId>org.jboss.arquillian.junit</groupId><artifactId>arquillian-junit-container</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!-- environment requirement --><dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>6.0</version><scope>provided</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.12.4</version><configuration><argLine>-XX:-UseSplitVerifier</argLine><systempropertyvariables><java.util.logging.config.file>${basedir}/src/test/resources/logging.properties</java.util.logging.config.file></systempropertyvariables><systemProperties><property><name>derby.stream.error.file</name><value>target/derby.log</value></property></systemProperties></configuration></plugin><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><compilerArguments><endorseddirs>${endorsed.dir}</endorseddirs></compilerArguments><showDeprecation>true</showDeprecation></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-ejb-plugin</artifactId><version>2.3</version><configuration><ejbVersion>3.1</ejbVersion></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>2.1</version><executions><execution><phase>validate</phase><goals><goal>copy</goal></goals><configuration><outputDirectory>${endorsed.dir}</outputDirectory><silent>true</silent><artifactItems><artifactItem><groupId>javax</groupId><artifactId>javaee-endorsed-api</artifactId><version>6.0</version><type>jar</type></artifactItem></artifactItems></configuration></execution></executions></plugin></plugins></build><repositories><repository><id>java.net</id><url>http://download.java.net/maven/</url></repository><repository><id>JBOSS_NEXUS</id><url>http://repository.jboss.org/nexus/content/groups/public</url></repository><repository><url>http://download.eclipse.org/rt/eclipselink/maven.repo/</url><id>eclipselink</id><layout>default</layout><name>Repository for library EclipseLink (JPA 2.0)</name></repository></repositories> </project>如上面的XML所示,我們所做的事情是:
- 包括使用Arquillian,使用嵌入式Glassfish
- 包括使用EclipseLink
- 設(shè)置Derby道具以備后用,即記錄和創(chuàng)建數(shù)據(jù)庫(kù)的位置。
創(chuàng)建“案例”,即我們的JPA,EJB,CDI
當(dāng)然,我們首先要?jiǎng)?chuàng)建一個(gè)案例,以便以后進(jìn)行測(cè)試。 我假設(shè)您熟悉JPA,EJB,CDI。 因此,下面是使用這些技術(shù)的類的快速概覽。
JPA類,Outlet.java
package id.co.dwuysan.inout.entity;// imports omitted@Entity @NamedQueries({@NamedQuery(name = Outlet.FIND_BY_NAME,query = "SELECT o FROM Outlet o WHERE o.name = :name") }) public class Outlet implements Serializable {public static final String FIND_BY_NAME = "Outlet#FIND_BY_NAME";@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@Column(name = "code", length = 50, insertable = true, updatable = false, unique = true)@Size(message = "{dwuysan.nameSizeError}", min = 1, max = 50)@NotNullprivate String name;/* Accessors and mutators goes here */@Overridepublic int hashCode() {// omitted}@Overridepublic boolean equals(Object obj) {// omitted} }Persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"><persistence-unit name="inoutPU" transaction-type="JTA"><provider>org.eclipse.persistence.jpa.PersistenceProvider</provider><jta-data-source>inoutDb</jta-data-source><exclude-unlisted-classes>false</exclude-unlisted-classes><properties><property name="eclipselink.ddl-generation" value="drop-and-create-tables"/></properties></persistence-unit> </persistence>然后,我們添加一個(gè)生產(chǎn)者方法以提供我們的PersistenceContext以及使用它的EJB。
EntityManagerProducer.java
package id.co.dwuysan.inout.util;import javax.enterprise.inject.Produces; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext;public class EntityManagerProducer {@Produces@PersistenceContextprivate EntityManager em; }OutletService.java
package id.co.dwuysan.inout.service;// imports omitted@Stateless @LocalBean public class OutletService {@Injectprivate EntityManager em;@Resourceprivate Validator validator;public Outlet createOutlet(final String name) {final Outlet outlet = new Outlet();outlet.setName(name);final Set<ConstraintViolation<Outlet>> violations = this.validator.validate(outlet);if (!violations.isEmpty()) { throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(violations)); }return this.em.merge(outlet);}public Outlet getOutlet(final String name) {final Query query = this.em.createNamedQuery(Outlet.FIND_BY_NAME);query.setParameter("name", name);try {return (Outlet) query.getSingleResult();} catch (NoResultException e) {return null;}} }設(shè)置beans.xml和ValidationMessages.properties
不要忘記:
- 在src / main / resources / META-INF下添加beans.xml ,并
- 在src / main / resources下添加ValidationMessages.properties ,并
- dwuysan.nameSizeError= error message you like here配置您的消息dwuysan.nameSizeError= error message you like here
配置用于測(cè)試目的
在這一點(diǎn)上,如果您部署,它應(yīng)該可以工作。 但是,這不是我們的目標(biāo)。 我們希望使用嵌入式Glassfish使它在Arquillian下工作。
首先,讓我們使用Derby數(shù)據(jù)庫(kù)準(zhǔn)備嵌入式玻璃魚(yú)的配置。 該文件是glassfish-resources.xml 。 就我而言,我只是將該文件放在一個(gè)新目錄下,主要用于分離,即src/test/resources-glassfish-embedded/glassfish-resources.xml 。
glassfish-resources.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE resources PUBLIC"-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN""http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> <resources><jdbc-resource pool-name="ArquillianEmbeddedDerbyPool"jndi-name="jdbc/arquillian"/><jdbc-connection-pool name="ArquillianEmbeddedDerbyPool"res-type="javax.sql.DataSource"datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource"is-isolation-level-guaranteed="false"><property name="databaseName" value="target/databases/derby"/><property name="createDatabase" value="create"/></jdbc-connection-pool> </resources>這是不言自明的。 只需記住將要配置的數(shù)據(jù)庫(kù)配置為在target/databases/derby上創(chuàng)建,以便在執(zhí)行mvn clean時(shí)將對(duì)其進(jìn)行清理。
下一步是配置Arquillian以“識(shí)別”此glassfish-resources.xml 。 為此,請(qǐng)?jiān)趕rc/test/resources目錄下添加arquillian.xml 。
glassfish-resources.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"><engine><property name="deploymentExportPath">target/arquillian</property></engine> <container default="true" qualifier="glassfish"><configuration><property name="resourcesXml">src/test/resources-glassfish-embedded/glassfish-resources.xml</property></configuration></container> </arquillian>下一步是準(zhǔn)備我們的persistence.xml 。 我們已經(jīng)有一個(gè),但要記住,我們需要提供一個(gè)它是在內(nèi)存中,并利用我們的嵌入式Glassfish的提供的JDBC連接(見(jiàn)glassfish-resources.xml上方,提供了jdbc-resource-pool下JNDI名稱為jdbc/arquillian ,在我的情況下,我將此名稱為test-persistence.xml命名為src/test/resources
test-persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"><persistence-unit name="inoutPU" transaction-type="JTA"><provider>org.eclipse.persistence.jpa.PersistenceProvider</provider><jta-data-source>jdbc/arquillian</jta-data-source><exclude-unlisted-classes>false</exclude-unlisted-classes><shared-cache-mode>ALL</shared-cache-mode><properties><property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /><property name="javax.persistence.jdbc.url" value="jdbc:derby:target/databases/derby;create=true" /><property name="eclipselink.ddl-generation" value="drop-and-create-tables" /><property name="eclipselink.target-database" value="Derby"/><property name="eclipselink.ddl-generation" value="drop-and-create-tables"/><property name="eclipselink.debug" value="OFF"/><property name="eclipselink.weaving" value="static"/><!--<property name="eclipselink.logging.level" value="FINEST"/>--><property name="eclipselink.logging.level.sql" value="FINE"/><property name="eclipselink.logging.parameters" value="true"/><!--<property name="eclipselink.logging.level.cache" value="FINEST"/>--><property name="eclipselink.logging.logger" value="DefaultLogger"/></properties></persistence-unit> </persistence>一切準(zhǔn)備就緒后,我們現(xiàn)在就可以與Arquillian一起編寫(xiě)單元測(cè)試了。 在這種情況下,最好測(cè)試我們的服務(wù)EJB,因?yàn)檫@是我們將使用JPA,CDI和Validation的地方。
OutletServiceTest.java
package id.co.dwuysan.inout.service;// imports omitted@RunWith(Arquillian.class) public class OutletServiceTest { @Injectprivate OutletService outletService;@Deploymentpublic static JavaArchive createTestArchive() {return ShrinkWrap.create(JavaArchive.class).addClass(Outlet.class).addClass(OutletService.class).addClass(EntityManagerProducer.class).addAsManifestResource("test-persistence.xml",ArchivePaths.create("persistence.xml")).addAsManifestResource("META-INF/beans.xml",ArchivePaths.create("beans.xml")).addAsResource("ValidationMessages.properties");}@Testpublic void testCreateOutlet() throws Exception {final String outletName = "Outlet 001";final Outlet outlet = this.outletService.createOutlet(outletName);Assert.assertNotNull(outlet);// check retrievalfinal Outlet retrievedOutlet = this.outletService.getOutlet(outletName);Assert.assertEquals(outlet.getName(), retrievedOutlet.getName());}@Test(expected = ConstraintViolationException.class)public void testCreateOutletWithEmptyName() throws Exception {try {final Outlet outlet = this.outletService.createOutlet("");} catch (EJBException e) { final ConstraintViolationException cve = (ConstraintViolationException) e.getCause();Assert.assertEquals("Total error message should only be one",1, cve.getConstraintViolations().size()); Assert.assertEquals("Message must be correct","Name must be provided",cve.getConstraintViolations().iterator().next().getMessage());throw cve;}} }在上面的示例中,第一個(gè)測(cè)試是測(cè)試成功的案例。 給定名稱,檢索將導(dǎo)致提供與參數(shù)相同名稱的Outlet實(shí)體返回。 但是,在表面之下,如果我們回顧OutletService.java的主體,我們實(shí)際上正在測(cè)試:
- 持久性(JPA),進(jìn)入基礎(chǔ)Derby
- EJB注入此測(cè)試/ li>
- 通過(guò)Producer方法(CDI)注入的PersistenceContext
- 測(cè)試沒(méi)有違反驗(yàn)證
- 測(cè)試我們的NamedQuery
第二項(xiàng)測(cè)試旨在測(cè)試消息是否正確內(nèi)插。 參考前面提到的內(nèi)容,對(duì)于我的錯(cuò)誤消息,我將以下條目放入ValidationMessages.properties :
dwuysan.nameSizeError=Name must be provided因此,我們需要測(cè)試來(lái)自“ Outlet驗(yàn)證”中的Bean驗(yàn)證的消息是否正確內(nèi)插。
請(qǐng)注意第二項(xiàng)測(cè)試。 注意,首先,我們正在捕獲EJBException 。 那是因?yàn)樵贓JB中拋出的任何運(yùn)行時(shí)異常都將被包裝到EJBException ,因此需要通過(guò)#getCause()提取它。
所以,你去了。 您現(xiàn)在可以添加更多服務(wù)并開(kāi)始Arquillian測(cè)試。 快樂(lè)編碼
未來(lái)調(diào)查
當(dāng)然,許多Java EE應(yīng)用程序都需要認(rèn)證和授權(quán),這通常是通過(guò)JAAS完成的。 例如,使用上面的簡(jiǎn)單示例,假設(shè)要修改服務(wù)以檢索當(dāng)前用戶可以訪問(wèn)的出口,那么我們當(dāng)然需要獲取當(dāng)前用戶的身份。 通常,這是通過(guò)EJBContext.getCallerPrincipal() . I wonder how we can do this using Arquillian and embedded Glassfish. EJBContext.getCallerPrincipal() . I wonder how we can do this using Arquillian and embedded Glassfish.
翻譯自: https://www.javacodegeeks.com/2013/09/testing-java-ee-6-with-arquillian-incl-jpa-ejb-bean-validation-and-cdi.html
ejb+jpa
總結(jié)
以上是生活随笔為你收集整理的ejb+jpa_使用Arquillian(包括JPA,EJB,Bean验证和CDI)测试Java EE 6的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 海洋面积占地球面积的多少(海洋面积占地球
- 下一篇: 月轮加速器电脑卡死(月轮加速器暂停)