Testing resource injection with Arquillian

After coding a simple component that uses an injected datasource to get a connection, we need to test it. To do so we should choose a testing tool  like JUnit and prepare some mock classes, run the tests, pass them and fail on production because running over the actual application server has some big differences.

This time it’s gonna be different.  From our toolbox we’ll take for a spin our brand new testing tool: the Arquillian framework. So, we’ll be running our test right to a JBoss AS 5.1 managed by the testing framework.

The application we’ll use is quite simple. An EJB component that saves an employee to the database. It doesn’t use JPA so we get a chance to inject a datasource and use it to get a connection. You can download the code from here.

Preparing the application to use Arquillian.

To begin at the very beginning the first thing you should do, if haven’t already, is add the JBoss repository into your maven settings. Then, since Arquillian is in alpha stage yet, you must get it from its git repository and build it yourself. Fun fact: Ike, the Arquillian logo, tells you whether is possible or not to build the source depending on its mood. Here some artwork and Ike’s moods.

Let’s begin by the pom configuration. Add the Arquillian JUnit dependency. It will get the binaries from your local repository since you  just built it.
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-junit</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>

Then, add a testing profile to manage the container to deploy to, In our case JBoss AS 5.1, and make sure the JBOSS_HOME variable is set.

<profile>
<id>jbossas-managed-5.1</id>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-jbossas-managed-5.1</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossas</groupId>
<artifactId>jboss-server-manager</artifactId>
<version>1.0.3.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossas</groupId>
<artifactId>jboss-as-client</artifactId>
<version>${container.jboss.5.1}</version>
<type>pom</type>
</dependency>
</dependencies>
</profile>

Optionally, if you need some extra configuration to reach your container installation or manipulate some other Arquillian defaults you can add an arquillian.xml file to your test/resources folder and configure them. I needed to specify where I wanted a copy of the deployed ear for the test and the instance it should be deployed to. Here you’ll find a reference to the containers configuration options.

<engine>
<deploymentExportPath>./target</deploymentExportPath>
</engine>

<jboss:container>
<jboss:profileName>test-field</jboss:profileName>
</jboss:container>

Write a test.

To tell JUnit that Arquillian is going to take over the test control you must annotate the test class with @org.junit.runner.RunWith.

@RunWith(Arquillian.class)
public class CreateEmployeeTest

Then you must prepare the archive that’s gonna hold the classes needed for running the test. This you do inside a method annotated with @org.jboss.arquillian.api.Deployment. The return for this method is an implementor of org.jboss.shrinkwrap.api.Archive representing a deployable unit like a war or jar file. We are testing some EJB here so we’ll return a JavaArchive.

@Deployment
public static JavaArchive createTestArchive()

The returning archive holds every resource necessary to run the test, so we need to add all the referenced classes, including the ones deeper inside the service we call from the EJB component used in the test class, and, other used resources like datasources. Classes can be add one by one or whole packages.

JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "test.jar");
archive.addPackages(true, EmployeeService.class.getPackage(), CommonDao.class.getPackage());
archive.addClasses(Employee.class);
archive.addResource("lunch-ds.xml", "lunch-ds.xml");

Finally we need at least one @org.junit.Test method invoking our EJB component to save employees in the database.

@Test
public void createEmployee() throws SQLException {
assertNotNull("Service wasn't injected. ", employeeService);
Employee employee = new Employee(0L, "iapazmino", "Iván", "Pazmiño");
employee = employeeService.save(employee);
assertNotSame("Employee id wasn't assigned. ", 0L, employee.getEmployeeId());
}

Running the test.

Change directory to the projects base and run test maven life-cycle.

$ cd workspace/sandbox/lunch-ejb
$ mvn test -Dtest=CreateEmployeeTest -Pjbossas-managed-5.1

This asks Arquillian to start the application server, deploy the test.jar and run the test. Here’s the outcome you get.

Trouble shooting.

If you get this error java.lang.ClassFormatError: Absent Code read this: What’s the cause of this exception: java.lang.ClassFormatError: Absent Code?

And that’s it for a beginning. Happy testing.

 

Advertisements

3 responses to “Testing resource injection with Arquillian

  1. Gracias dr, ya lo estoy usando!

  2. Nice article! Added it to Arquillians front page external feeds.

    Just noticed a little ting; you forgot to explain how you get a EmployeService instance.
    (it’s just there the @Test method)

    🙂

  3. Hello there, you have got some nice things here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s