In this tutorial we will learn how to integrate tests with Arquillian using TomEE Application Server.
Tools You Will Need
Maven 3.3+
Your favorite IDE
JDK 1.8+
Git
Clone the TomEE Starter Project from Github
$ git clone https://github.com/cicekhayri/tomee-javaee-crud-rest-starter-project.git
Now it's time to add some dependencies.
Open the project in your favorite IDE and add the following to the pom.xml
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>3.1.3</version>
<scope>test</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>arquillian-tomee-remote</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
<version>1.4.0.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>tomee-jaxrs</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
We added Arquillian dependencies and your pom.xml should look like this now :
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kodnito</groupId>
<artifactId>restapi</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<tomee.version>7.0.5</tomee.version>
<javaee.api>7.0</javaee.api>
<jackson.version>2.9.6</jackson.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee.api}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>3.1.3</version>
<scope>test</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>arquillian-tomee-remote</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
<version>1.4.0.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>tomee-jaxrs</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomee.maven</groupId>
<artifactId>tomee-maven-plugin</artifactId>
<version>${tomee.version}</version>
<configuration>
<tomeeVersion>${tomee.version}</tomeeVersion>
<tomeeClassifier>plus</tomeeClassifier>
</configuration>
</plugin>
</plugins>
</build>
</project>
In project directory run the following command to download the dependencies.
$ mvn install
Inside src/test/java/com/kodnito/it/rest/ package create TodoEndpoint.java and add the following :
package com.kodnito.it.rest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kodnito.restapi.entity.Todo;
import java.io.File;
import java.net.URL;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Assert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(Arquillian.class)
public class TodoEndpointTest {
@ArquillianResource
private URL webappUrl;
WebTarget target;
ObjectMapper om = new ObjectMapper();
@Before
public void before() throws Exception {
target = ClientBuilder.newClient().target(webappUrl.toURI()).path("api");
}
@Deployment
public static WebArchive createDeployment() {
File[] files = Maven.resolver().loadPomFromFile("pom.xml")
.importRuntimeDependencies().resolve().withTransitivity().asFile();
WebArchive war = ShrinkWrap.create(WebArchive.class)
.addAsLibraries(files)
.addPackages(true, "com.kodnito.restapi")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml");
System.out.println(war.toString(true));
return war;
}
@Test
@InSequence(1)
@RunAsClient
public void shouldCreateTodo() throws Exception {
Todo todo = new Todo();
todo.setTask("this is task");
todo.setDescription("this is description");
String todoJsonString = om.writeValueAsString(todo);
final Response response = target
.path("todos")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.json(todoJsonString));
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
}
@Test
@InSequence(2)
@RunAsClient
public void shouldGetAllTodos() throws Exception {
final Response response = target.path("todos")
.request(MediaType.APPLICATION_JSON_TYPE)
.get();
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
JsonNode json = om.readTree(response.readEntity(String.class));
Assert.assertTrue(json.size() > 0);
}
@Test
@InSequence(3)
@RunAsClient
public void shouldGetByTodoId() throws Exception {
final Response response = target.path("todos")
.path("1")
.request(MediaType.APPLICATION_JSON_TYPE)
.get();
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
JsonNode json = om.readTree(response.readEntity(String.class));
assertNotNull("Response contains id ", json.get("id").asLong());
assertEquals(1L, json.get("id").asLong());
}
@Test
@InSequence(4)
@RunAsClient
public void shouldPut() throws Exception {
Todo todo = new Todo();
todo.setId(1L);
todo.setTask("this is updated task");
todo.setDescription("this is updated description");
String todoUpdateString = om.writeValueAsString(todo);
final Response response = target.path("todos")
.path("1")
.request(MediaType.APPLICATION_JSON_TYPE)
.put(Entity.json(todoUpdateString));
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
}
@Test
@InSequence(5)
@RunAsClient
public void shouldDelete() throws Exception {
final Response response = target.path("todos")
.path("1")
.request(MediaType.APPLICATION_JSON_TYPE)
.delete();
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
}
}
@RunWith(Arquillian.class) annotation tells JUnit to use Arquillian as controller.
@ArquillianResource annotation will inject url and only works on in-container tests.
@Deployment annotation is used to define which methods should be considered as deployment producer.
@Test annotation tells JUnit that the method can be run as a test case.
@InSequence annotation is used to order the execution flow of the @Test methods
@RunAsClient annotation will execute the test methods on the client side.
om.writeValueAsString() methods is used to serialize any Java value as a String.
om.readTree() method will parse JSON content into JsonNode object.
assertEquals() checks that two objects are equal.
assertNotNull() checks that an object is not null.
Assert.assertTrue() checks that condition is true.
shouldCreateTodo() method tests the creation of creating Todo object.
shouldGetAllTodos() method tests to get a list of todos.
shouldGetByTodoId() method tests getting Todo object by id.
shouldPut() method tests updating Todo object.
shouldDelete() method tests deleting of Todo object.
Your project structure should look like this
tree . . ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── kodnito │ │ └── restapi │ │ ├── entity │ │ │ └── Todo.java │ │ ├── rest │ │ │ ├── ApplicationConfig.java │ │ │ └── TodoEndpoint.java │ │ └── service │ │ └── TodoService.java │ ├── resources │ │ └── META-INF │ │ └── persistence.xml │ └── webapp │ └── WEB-INF │ ├── beans.xml │ └── resources.xml └── test ├── java │ └── com │ └── kodnito │ └── it │ └── rest │ └── TodoEndpointTest.java └── resources └── arquillian.xml
Now in the project directory run the following command :
$ mvn clean test
In this tutorial we learned how to integrate test with Arquillian and TomEE.
Clone the final project from GitHub
$ git clone https://github.com/cicekhayri/tomee-javaee-crud-rest-arquillian-project.git
Share this: