We are configured our project to create and run tests with Arquillian. Here i will explain how to create a simple test using Arquillian and JPA.
We have created a data source with JNDI-name "jdbc/sample" in part 1, we will use it for our JPA test, i have used an API to make generic DAOs and hibernate-entity-manager as an entitity manager, needed dependencies therefore :
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.7.Final</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.7.Final</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- generic DAO dependencies -->
<!-- This first dependency includes all the JPA implementations for the DAOs -->
<dependency>
<groupId>com.googlecode.genericdao</groupId>
<artifactId>dao</artifactId>
<version>1.0.0</version>
</dependency>
<!-- This second one includes the Hibernate Entity Manager plugin for the framework -->
<dependency>
<groupId>com.googlecode.genericdao</groupId>
<artifactId>search-jpa-hibernate</artifactId>
<version>1.0.0</version>
</dependency>
<!-- end of generic DAO dependencies -->
I've created a BaseDAO interface and then the a specific interface to provide CRUD operations for users.
/**
* @author Hasan Oezdemir
* @since 01.10.2011
*
*/
public interface BaseDAO<T, ID extends Serializable> extends GenericDAO<T, ID> {
-
public T findByExampleUnique(T example);
}
/**
* @author Hasan Oezdemir
* @since 01.10.2011
*
*/
public interface UserDAO extends BaseDAO<User, Long> {
}
And an abstract class for JPA implementations :
/**
* @author Hasan Oezdemir
* @since 01.10.2011
*
*/
public abstract class JPAGenericDAO<T, ID extends Serializable> extends GenericDAOImpl<T, ID> implements
BaseDAO<T, ID> {
private static final Logger logger = LoggerFactory.getLogger(JPAGenericDAO.class);
@PersistenceContext(unitName="sample")
private EntityManager entityManager;
public JPAGenericDAO(){
super();
}
@PostConstruct
public void initialized(){
this.setEntityManager(entityManager);
JPASearchProcessor searchProcessor = new JPASearchProcessor(new JPAAnnotationMetadataUtil());
this.setSearchProcessor(searchProcessor);
}
-
public T findByExampleUnique(T example) {
Search s = this.createSearch(example);
return searchUnique(s);
}
-
-
Search s = this.createSearch(example);
return search(s);
}
protected Search createSearch(T example) {
Search s = new Search(example.getClass());
s.addFilter(this._getFilterFromExample(example));
return s;
}
}
As you remember we are created a persistence-unit named "sample" while injecting the entity-manager at this point, we are used this unit for our DAOs :
@PersistenceContext(unitName="sample")
private EntityManager entityManager
And a reference implementation for our JPA DAO :
/**
* @author Hasan Oezdemir
* @since 01.10.2011
*
*/
@Singleton
public class JPAUserDAO extends JPAGenericDAO<User, Long> implements UserDAO {
public JPAUserDAO(){
super();
}
}
We are now ready to implement an Arquillian Test for our JPA class.The most important section to create a static method annotated with @Deployment to build a ShrinkWrap, here is a sample method:
/**
* Since Arquillian actually creates JAR files under the covers with
* ShrinkWrap, the @Deployment is your way of controlling what is included
* in that Archive. Note, each class utilized in your test case - whether
* directly or indirectly - must be added to the deployment archive.
*/
@Deployment
public static Archive<?> createTestArchive() {
return ShrinkWrap
.create(JavaArchive.class, "test.jar")
.addAsResource("arquillian.xml")
.addPackages(true, UserDAO.class.getPackage())
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsManifestResource("META-INF/persistence.xml",
ArchivePaths.create("persistence.xml"));
}
We must add our arquillian configuration too, otherwise ShrinkWrap reads the default configuration and ignores our configuration.
I've created an abstract class which is extended by all test-classes :
/**
*
* @author Hasan Oezdemir
* @since 02.10.2011
*
*/
public class AbstractJPATest {
/**
* Since Arquillian actually creates JAR files under the covers with
* ShrinkWrap, the @Deployment is your way of controlling what is included
* in that Archive. Note, each class utilized in your test case - whether
* directly or indirectly - must be added to the deployment archive.
*/
@Deployment
public static Archive<?> createTestArchive() {
return ShrinkWrap
.create(JavaArchive.class, "test.jar")
.addAsResource("arquillian.xml")
.addAsResource("log4j.xml")
.addPackages(true, UserDAO.class.getPackage())
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsManifestResource("META-INF/persistence.xml",
ArchivePaths.create("persistence.xml"));
}
@Inject
protected UserTransaction userTransaction;
public AbstractJPATest() {
super();
}
/**
* @throws java.lang.Exception
*/
@Before
-
this.userTransaction.begin();
}
/**
* @throws java.lang.Exception
*/
@After
-
try {
this.userTransaction.rollback();
-
-
}
}
/**
* @return a test user.
*/
protected User createUser() {
User user = new User();
user.setEmail("hasan@hotmail.com");
user.setName("hasan");
user.setPassword("12345");
return user;
}
}
Transaction management may be better but this is enought for now :)
We must run our tests with Arquillian.class therefore we should add @RunWith(Arquillian.class) for each our tests-classes, here is a sample :
/**
* @author Hasan Oezdemir
* @since 01.10.2011
*
*/
@RunWith(Arquillian.class)
public class JPAUserDAOTest extends AbstractJPATest {
@Inject
private JPAUserDAO jpaUserDAO;
/**
* Test method for
* {@link com.citecompany.dao.jpa.JPAGenericDAO#findByExampleUnique(java.lang.Object)}
* .
*/
@Test
public void testFindByExampleUnique() {
User user = this.createUser();
this.jpaUserDAO.save(user);
User found = this.jpaUserDAO.findByExampleUnique(user);
assertNotNull("Expected user " + user + " is not found in data source.", found);
assertEquals(user.getName(), found.getName());
}
}
So our test class is ready to start, you start it either with maven or in eclipse.