So here is what I had to do:
1. Add a profile for running the Arquillian Integration tests in Maven
<profiles>
<profile>
<id>it</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<defaultGoal>verify</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
</build>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-jbossas-remote-5.1</artifactId>
<version>1.0.0.Alpha4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.jbossas</groupId>
<artifactId>jboss-as-client</artifactId>
<version>5.1.0.GA</version>
<type>pom</type>
</dependency>
</dependencies>
</profile>
</profiles>
2. Make sure you are using the correct version of the javassist library in your business logic project. It has to be version 3.10.0.GA. The one coming with JBoss AS 5.1.0 GA is older (3.9.0) and will not work properly!
3. Write your test classes and run them using "mvn -Pit"!
4. Here is an example of a simple class just calling a EJB3 SLSB (test-persistence.xml has to be in src/test/resources together with jndi.properties):
import javax.naming.Context; import javax.naming.InitialContext; import junit.framework.Assert; import myclasses.ejb.actions.interfaces.AuthenticatorLocal; import myclasses.ejb.valueobjects.RequestorInfo; 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.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class AuthenticatorBeanIT { @Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class, "testAuthenticatorBean.jar") .addClasses(AuthenticatorBean.class, AuthenticatorLocal.class, RequestorInfo.class) .addManifestResource("test-persistence.xml", ArchivePaths.create("persistence.xml")); } @Test public void isAuthenticatedTest() throws Exception { Context ctx = new InitialContext(); AuthenticatorLocal auth; Object obj = ctx.lookup("AuthenticatorBean/local"); auth = (AuthenticatorLocal) obj; RequestorInfo req = new RequestorInfo(); // Trying with a valid user (according to import.sql!) req.setRequestorId("0123456789"); req.setPassword("secret"); Assert.assertTrue(auth.isAuthenticated(req)); // Trying with a invalid user req.setRequestorId("0123456789"); req.setPassword("incorrect"); Assert.assertFalse(auth.isAuthenticated(req)); } }
5. Here is an example of a class persisting something to the DB and cleaning up after itself (Note: you have to lookup the EntityManager and EntityTransaction yourself. They can not be injected since you are not in an EJB(:
import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.naming.Context; import javax.naming.InitialContext; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Query; import junit.framework.Assert; import myclasses.ejb.actions.interfaces.MyClassLocal; import myclasses.ejb.valueobjects.Info; 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.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class BarCodeBoardingPassBeanIT { @Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class, "testBarCodeBoardingPassBean.jar") .addClasses(MyClassLocal.class) .addManifestResource("test-persistence.xml", ArchivePaths.create("persistence.xml")); } @Test public void persistBoardingPassInfoTest() throws Exception { Context ctx = new InitialContext(); MyClassLocal mcl; Object obj = ctx.lookup("MyClasssBean/local"); mcl = (MyClassLocal) obj; Info info = new Info("XXX"); mcl.persistInfo(info); // Now checking that the data is properly persisted in the DB EntityManagerFactory emFactory = (EntityManagerFactory) ctx.lookup("java:/myTestEntityManagerFactory"); EntityManager em = emFactory.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Query query = em.createQuery("From Info where text=:info"); query.setParameter("info", "XXX"); runQuery(query); // Cleaning up query = em.createQuery("delete from Info where text=:info"); query.setParameter("info", "XXX"); query.executeUpdate(); tx.commit(); } private void runQuery(Query query) { try { query.getSingleResult(); Assert.assertTrue(true); } catch (Exception e) { Assert.assertTrue(false); } } }
6. For the previous test class to work you need a persistence.xml which looks like this:
<?xml version="1.0" encoding="UTF-8"?> <persistence 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_1_0.xsd" version="1.0"> <persistence-unit name="myTestPU" transaction-type="RESOURCE_LOCAL" > <provider>org.hibernate.ejb.HibernatePersistence</provider> <non-jta-data-source>java:/myAppDS</non-jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <property name="hibernate.current_session_context_class" value="jta"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.default_schema" value="public"/> <property name="hibernate.hbm2ddl.auto" value="validate" /> <property name="jboss.entity.manager.factory.jndi.name" value="java:/myTestEntityManagerFactory"/> </properties> </persistence-unit> </persistence>
Doesn't Arquillian support JUnit startup and teardown methods (annotations)? That's at least where you write your cleanup code (tearDown())
Shervin, this is quite possible... I did not think of it actually! I will investigate :)
Thank you for this! Just what I was looking for.