Mittwoch, 9. Februar 2011

Arquillian - EJB3.1 Unit testing with JTA

In the last days i read a lot and testet much to see how integration testing / unit testing with stateless and stateful session beans could work. I found out that JavaEE6 introduced stuff like the EJBContainer, embedded glassfish and jboss appservers and some nice things like that. I managed to start and stop an embedded server and also posted in my last post how to add a datasource to this embedded glassfish (see this article). Now if you even want it to be another step simpler and easier, I would even recommend you to use a project called Arquillian. This tool uses ShrinkWrap to create a war file at unit test runtime, start your embedded server, deploy your war, start your tests and shutdown your embedded server again. What else would you wish? ;) It supports GlassFish, JBoss and some other appservers I guess... So give it a try.

There is just a couple of files you need. As earlier mentioned...
- the sun-resources.xml
- a persistence-test.xml using JTA (an example could be found in this article)
- a arquillian.xml file which could look like the following:


<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.com/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfembed="urn:arq:org.jboss.arquillian.container.glassfish.embedded_3">
<gfembed:container>
<gfembed:sunResourcesXml>src/test/resources/sun-resources.xml</gfembed:sunResourcesXml>
</gfembed:container>
</arquillian>


All of these files should reside in src/test/resources. And a unit test class could then look like this:


package de.mortensenit.myproduct.dao.jpa;

import de.mortensenit.myproduct.dao.AccountServiceDao;
import de.mortensenit.myproduct.model.Client;
import de.mortensenit.myproduct.model.User;
import java.io.File;
import javax.inject.Inject;
import static junit.framework.Assert.*;
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class AccountServiceDaoJpaTest {

@Inject
private AccountServiceDao dao;

@Deployment
public static WebArchive createTestArchive() {
return ShrinkWrap.create(WebArchive.class, "test.war")
.addClasses(AccountServiceDaoJpa.class)
.addLibrary(new File("target/myproduct-model-1.0-SNAPSHOT.jar"))
.addManifestResource("persistence-test.xml", "persistence.xml")
.addManifestResource("sun-resources.xml")
.addWebResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));
}

@Test
public void testFindClient() {
Client client = new Client();
client.setId("94aac911-189b-40cd-a03f-860c84fce3f2");
Client result = dao.find(Client.class, client);
assertEquals("94aac911-189b-40cd-a03f-860c84fce3f2", result.getId());
}


}


Last, but not least the pom.xml for the dependencies:

<?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>myproduct</artifactId>
<groupId>de.mortensenit.myproduct</groupId>
<version>1.0-SNAPSHOT</version>
</parent>

<groupId>de.mortensenit.myproduct</groupId>
<artifactId>myproduct-jpa</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>ejb</packaging>
<name>myproduct-jpa</name>

<repositories>
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>glassfish-repository</id>
<name>Java.net Repository for Glassfish</name>
<url>http://download.java.net/maven/glassfish</url>
</repository>
<repository>
<id>java.net2</id>
<name>Java.Net Maven2 Repository, hosts the javaee-api dependency</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>EclipseLink Repo</id>
<url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3</artifactId>
<version>1.0.0.Alpha4</version>
</dependency>
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.0.1-b02</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-junit</artifactId>
<version>1.0.0.Alpha4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.0-801.jdbc4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>de.mortensenit.myproduct</groupId>
<artifactId>myproduct-model</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.mortensenit.myproduct</groupId>
<artifactId>myproduct-dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

<build>
<plugins>
<!--
following plugin copies model jar into target folder because
the persistence unit needs it for the unit tests
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>de.mortensenit.myproduct</groupId>
<artifactId>myproduct-model</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.1</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>endorsed</id>
<activation>
<property>
<name>sun.boot.class.path</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<compilerArguments>
<bootclasspath>${settings.localRepository}/javax/javaee-endorsed-api/6.0/javaee-endorsed-api-6.0.jar${path.separator}${sun.boot.class.path}</bootclasspath>
</compilerArguments>
</configuration>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>6.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server>
</properties>
</project>


For a deeper insight and good start, read also the following article:

http://community.jboss.org/en/arquillian/blog/2010/10/04/the-perfect-recipe-for-testing-jpa-2-revisited

By the way, a big thanks goes out to Adam Bien, aslak and jdlee for their help on this topic ;)

Keine Kommentare:

Kommentar veröffentlichen

Hier kann jeder (auch unregistrierte) Leser seine Meinung kundtun...