Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Integration Testing with CDI, JPA, EJB and Arquillian

In this article we will see an introduction to Arquillian and how to use it. We will see how to create and enrich your integration tests using some key features of Java EE like CDI, JPA and EJB, and executing them in WildFly

Before you know better Arquillian is interesting to consider some terminology that we will address in this article:

  • Container: A runtime environment for a deployment;
  • Implementation: The process of sending an artifact to a container to make it operational;
  • File: A packaged set of code, configuration and resources.

The Arquillian is a test platform for Java, which allows developers to write and perform integration tests and functional simple. Basically, the advantage Arquillian JUnit or TestNG to execute test cases against a Java container (e.g., GlassFish).

In addition, the Arquillian handles all the plumbing of containers management, implementation and startup, leaving only the developer to focus on business logic in which the test is being written. Instead of setting up a potentially complex test equipment, Arquillian abstracts that at run time, like this:

  • Management life cycle(s) of container(s);
  • Does aggregation(s) test case(s), dependent classes and resources in a ShrinkWrap file (show more on);
  • Performs deployment(s) file(s) in(s) container(s);
  • Enrich the case(s)(s) test(s), providing dependency injection and other services declarative Java EE;
  • Run the tests inside the container;
  • Capturing test results, then immediately returns the results to the testing hall (for example, JUnit) so as to be displayed in the IDE;
  • The Arquillian integrates seamlessly with test frameworks (eg, JUnit 4, TestNG 5), allowing the tests can be launched using IDE, Ant and Maven, without any add-ons.

In turn, the Arquillian in its architecture provides a test runner adapted to JUnit and TestNG, allowing the testing framework perform the same cycle with the Arquillian. The ShrinkWarp is used to set declaratively which files (eg classes) will be used, thus making the packing of classes and their dependent resources, then it is deployed and run on the target container, after running the test results are captured. Finally, the Arquillian undeploys the file and shows the test results using the testing hall (for example, TestNG). See Figure 1 as Arquillian architecture is composed.

Figure 1. Hows the architecture of Arquillian

Finally, another key point about Arquillian is that it has three styles of interaction with the containers, they are:

  • Container Remote: The Arquillian makes use of a container already running, that is, the server must already be running to deploy the test suite is performed and executed;
  • Container Managed: It is similar to the remote container except its life cycle (startup / shutdown) that is managed by Arquillian;
  • Container built (or embedded): The Arquillian simply climbs a container instance (eg WildFly) within the test itself.

We will see in sequence to create integration tests using CDI, EJB and JPA with the support of Arquillian through the Maven project and run them in WildFly, but before that, we will emphasize in the next section the main tools that we will use.

Used tools

We will use Arquillian (see Links section) along with the Eclipse IDE and Java EE perspective. The version used in this article is the Eclipse Mars (4.5 - see Links section), but you can use another version of Eclipse that supports Java EE.

Apache Maven is a software project management tool and understanding based on the concept of a project object model (POM), which can manage a construction project, reporting and documentation from a central piece of information. Thus, the version used in this article is the Maven 3.3.3 (Links section), but you can use another version.

JUnit is an open-source framework that supports the creation of automated tests in Java programming language, and the version used in this article is 4.11 (in the Links section you have the link to the version).

Creating a new project

Let's now create a new Maven project so we can add dependencies like JUnit, Arquillian and other settings in the pom.xml file.

First start the Eclipse IDE and then select "File> New> Other ..." and "Maven> Maven Project". Click "Next" and on the next screen select the checkbox "Create a simple project" and click "Next" again. In the window that appears fill in the fields "Group Id" and "Artifact Id" and click "Finish".

Project Setup

After creating the Maven project, if your project is using a different version of Java which you use, we can set this up. This happens because if you did not declare in the pom.xml explicitly the version of Java that the project should be built, Maven will assume by default Java 1.5. As an example, we show how to configure Java 1.5 to 1.8.

Open the pom.xml file and add the code from Listing 1 between the tags so we can use the version of Java 1.8 in Maven project (created earlier).

Listing 1. Build code with the configuration of the Maven project build with Java 1.8

<build>
        <plugins>
              <plugin>
                    <artifactId> maven-compiler-plugin </ artifactId>
                    <!-- Maven plugin version ->
                    <version> 3.1 </ version>
                    <configuration>
                    <!-- Java version ->
                          <Source> 1.8 </ source>
                          <Target> 1.8 </ target>
                    </ configuration>
              </ plugin>
        </ plugins>
  </ build>

Soon after, select the project and run the Maven Project Update using the Alt + F5 or right mouse choosing "Maven> Update Project" option. Then, the Maven project is already able to use the Java 1.8.

Also in the pom.xml file add the code in Listing 2 for the Maven project perform the tests with Arquillian.

Listing 2. Dependencies necessary

<dependencyManagement>
        <dependencies>
              <!-- Arquillian Jboss -->
              <dependency>
                    <groupId>org.jboss.arquillian</groupId>
                    <artifactId>arquillian-bom</artifactId>
                    <version>1.1.4.Final</version>
                    <type>pom</type>
                    <scope>import</scope>
              </dependency>
        </dependencies>
  </dependencyManagement>
   
  <dependencies>
        <!-- Arquillian JUnit Container -->
        <dependency>
              <groupId>org.jboss.arquillian.junit</groupId>
              <artifactId>arquillian-junit-container</artifactId>
              <scope>test</scope>
        </dependency>
              <!-- JUnit -->
        <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.11</version>
  <scope>test</scope>
        </dependency>
        <!-- Java EE 7 API -->
        <dependency>
              <groupId>javax</groupId>
              <artifactId>javaee-api</artifactId>
              <version>7.0</version>
        </dependency>
  </dependencies>

We must also add the pom.xml the profile that contains the link to the container that will be called by Arquillian. So, add the code in Listing 3.

Listing 3. Profile WildFly 8.1.0 managed in pom.xml file

 <profiles>
        <-- Profile of WildFly 8.1.0 of managed type -->
              <profile>
                    <id>jboss</id>
                    <dependencies>
                          <dependency>
                               <groupId>org.wildfly</groupId>
                               <artifactId>wildfly-arquillian-container-managed</artifactId>
                               <version>8.1.0.Final</version>
                               <scope>test</scope>
                               <!-- Delete the unnecessary call jconsole (we will not use it) -->
                               <exclusions>
                                     <exclusion>
                                           <groupId>sun.jdk</groupId>
                                           <artifactId>jconsole</artifactId>
                                     </exclusion>
                               </exclusions>
                          </dependency>
                    </dependencies>
              </profile>
        </profiles>

Note that the code contains between the profile tags (called jboss) that points to the container WildFly 8.1.0 of managed type. If desired, they can be added other profiles to call other containers. For us to use this profile first select the Maven project and then right-click choose "Maven> Select Maven Profiles" or press Ctrl + Alt + P. Finally select the profile "jboss" and click ok.

If you do not have WildFly on the computer, this container we are using is version 1.8.0.final. To complete the configuration, create a file called "arquillian.xml" in the\src\test\resources\arquillian.xml putting content in Listing 4. Remember to change the container path (WildFly) in the tag "jbossHome”.

Listing 4. Arquillian.xml file configuration containing the URLde location WildFly 1.8.0.final (located on the computer).

<?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">
   
        <container qualifier="jboss" default="true">
              <configuration>
                    <property name="jbossHome"><place here an absolute path or relative WildFly >\wildfly-8.1.0.Final</property>
              </configuration>
        </container>
  </arquillian>

Note that in pom.xml file that contains the WildFly profile has the id "jboss", which in turn has a connection with qualifier "jboss" the arquillian.xml file in Listing 4. However, it is important to keep the same name, it helps the Arquillian the container identification to be called for execution.

And to complete the project setup we need to create an empty file called beans.xml in /src/main/resources/META-INF/beans.xml directory so we can use the CDI. Finally, we should use persistence.xml the JPA create the file called beans.xml the same directory with the contents of Listing 5.

Listing 5. persistence.xml file with the connection settings

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">
 
 
 
 java:jboss/datasources/ExampleDS

Note that in the persistence.xml file we are using the connection to the H2 database already preconfigured in WildFly if wanted to change to another data source (eg MySQL, PostgreSQL and others) is only change and put between the tags.

Developing tests using CDI, EJB and JPA with Arquillian

After made the necessary settings, for the sake of organization, we need to create some packages. With this, select the directory (/src/main/java) and create a package called "com.mrbool.arquillian.modelo", and then create a class (or entity) called "Person.java" with content Listing 6.

Listing 6. Class Code Person.java

  @Entity
  @Table(name = "person")
  public class Person implements Serializable {
   
        private static final long serialVersionUID = 1L;
   
        @Id
        @GeneratedValue
        @Column(name = "id")
        private int id;
        @Column(name = "name", length = 60)
        private String name;
        @Column(name = "age")
        private Integer age;
   
        public int getId() {
              return id;
        }
   
        public void setId(int id) {
              this.id = id;
        }
   
        public String getName() {
              return name;
        }
   
        public void setName(String name) {
              this.name = name;
        }
   
        public Integer getAge() {
              return age;
        }
   
        public void setAge(Integer age) {
              this.age = age;
        }
  }

We have to add the class Person.java in the persistence.xml file between tags (for example, still use com.mrbool.arquillian.modelo.Person) for this entity to be managed.

Next, select the directory (/src/main/java) and create the package named "com.mrbool.arquillian.dao" and it creates a class called "PersonDao.java" containing the Listing 7 code.

Listing 7. Class Code PersonDao.java

 
  @Stateless
  public class PersonDao {
   
        @PersistenceContext (UnitName = "test")
        EntityManager em;
   
        public void save (Person p) {
              em.persist (w);
        }
        
        public void update (Person p) {
              em.merge (w);
        }
   
        public Person seek (int id) {
              return em.find (Person.class, id);
        }
   
        public List <Person> searchAllPersons () {
              em.createQuery return ( "SELECT p FROM Person p ORDER BY p.id" Person.class) .getResultList ();
        }
  }

Now we will create another class to test the PersonDao class and then run the tests using the managed server WildFly 8.1.0. Since the focus of this article is Arquillian, we detail some important points about it below.

In the /src/test/java create a package called "com.mrbool.arquillian.dao" and it creates a class called "PersonDaoTest.java" adding the Listing 8 code.

Listing 8. Code for operating the Arquillian

 @RunWith(Arquillian.class)
public class PersonDaoTest{
  @Deployment
 public static Archive<?> createFileTest() {
  Archive<?> arquivoTest = ShrinkWrap.create(WebArchive.class, "applicationTest.war")
  
.addPackage(PersonDao.class.getPackage())
  .addClass(Person.class)
  .addAsResource("META-INF/persistence.xml")
  .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
  return arquivoTest;
 }
}

Note that in PersonDaoTest class notation "@RunWith" tells JUnit to use Arquillian as the test driver. Another highlight is the notation "@Deployment" which makes what Arquillian run the static method "createFileTest ()", which performs the implantation including all specified classes and resources (rather than deploying the entire application), whereas this part to include these files is the responsibility ShrinkWrap API.

Note that in Listing 8, rather than included class by class (for example, .addClass(Person.class) method), use the AddPackage method which adds all the classes that are contained in the same class package, as is the PessaoDaoTest with inclusion of .addPackage method (PersonDao.class.getPackage()), that is, this method will include all other classes that are in the same package as the class PerssoaDao. On the other hand, it can also be done adding class by class by a single method called .addClasses, for example:

.addClasses (Person.class, PerssoaDao.class) 

And in order to use IDUs in tests we add the .addAsWebInfResource method (EmptyAsset.INSTANCE, "beans.xml"), and the same way does the JPA including .addAsResource("META-INF/persistence.xml") method. These methods tell the ShrinkWrap to include these configuration files within the application "applicationTest.war".

Now we can enjoy the power that gives us Arquillian. Remembering that we can write the tests using the capabilities of Java EE 7 usually within a test class. Note that previously created the class "PersonDao" and "PersonDaoTest" only a matter of responsibility, but that does not stop in a class only use the features of Java EE, but the requirement we have is that the class is configured with the Arquillian. Now add the @Inject annotation above the PerssoaDao variable in order to use the injection CDI dependence, as shown in the following code:

 @Inject
  PersonDao PersonDao;

It may happen that, instead of using the @Inject, it may be replaced by the @EJB annotation, for PersonDao class is marked with the annotation @Stateless. However, we will use the same @Inject because the CDI through @Inject allows inject objects they are EJBs or not. Finally, add in Listing 9 tests in PessaoDaoTest.java class.

Listing 9. Code with testing

@Test
@InSequence(1)
public void testSavePerson() {
   Person p1 = new Person();
   p1.setAge(10);
   p1.setName("John Snow");
   personDao.salvar(p1);
 
   Person p2 = new Person();
   p2.setAge(21);
   p2.setName("Phelipe Star");
   personDao.salvar(p2);
   
}
   
@Test
@InSequence(2)
public void testUpdatePersonP1() {
   Person p1 = personDao.search(1);
   p1.setName("Peter");
   p1.setAge(11);
   personDao.atualizar(p1);
   
   assertEquals("Peter", p1.getName());
   assertEquals(11, p1.getAge().intValue());
   
}
  
@Test
@InSequence(3)
public void testSearchPersonP2() {
   Person p2 = personDao.buscar(2);
   
   assertEquals("Phelipe Star", p2.getName());
   assertEquals(21, p2.getAge().intValue());
}
   
@Test
@InSequence(4)
public void testSearchAllPersons() {
    List<Person> persons = personDao.searchAllPersons();
    assertEquals(2, persons.size());
}

Note that the code used to @Test annotation that tells JUnit noted that the method should be executed during testing. Moreover, we dictate their execution order by @InSequence() note.

To run them select the test class "PersonDaoTest" and then click the right mouse button select "Run As> JUnit Test" option.

All the tests are marked with green, which means that all passed, and we managed the feat to perform our tests as if they were in production. Thus, we see the great advantage of Arquillian, which is to provide and give freedom to a developer and use Java EE resources in the tests, and thus is considered an excellent framework to support the test.

I hope this article has helped and contributed to the construction and application of knowledge about Arquillian.

Thank you and more!

Links

JUnit

http://junit.org/

Maven

https://maven.apache.org/

Arquillian

http://arquillian.org/

ArquillianDocumentation

https://docs.jboss.org/author/display/ARQ/Container+adapters?_sscc=t



Web developer and passioned for web design, SEO and front end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login