Kohei Nozaki's blog 

Arquillian EJB-JAR/EAR testing examples


Posted on Friday Mar 20, 2015 at 10:33AM in Arquillian


There are plenty of examples of Arquillian testing with WAR deployments, but not for other deployments such as EJB-JAR or EAR. so I created some examples. these examples were tested against Arquillian 1.1.7.Final, using WildFly 8.2.0.Final as remote container. the entire project can be obtained from GitHub.

Testing against EJB-JAR deployment

Assume we have a simple EJB in a EJB-JAR project as follows:

@Stateless
@LocalBean
public class SomeEjb {
    public String hello(String name) {
        return "Hello, " + name;
    }
}

Test class:

@RunWith(Arquillian.class)
public class EjbJarIT {
    @Deployment
    public static Archive<?> createDeploymentPackage() {
        final Archive archive = ShrinkWrap.create(JavaArchive.class).addClass(SomeEjb.class);
        return archive;
    }

    @EJB
    private SomeEjb someEjb;

    @Test
    public void test() {
        Assert.assertEquals("Hello, Kyle", someEjb.hello("Kyle"));
    }
}

The deployment will be a WAR through Arquillian’s automatic enrichment process while the method annotated as @Deployment produced JavaArchive.

Testing against EAR deployment

Assume we have a simple EAR project which depends on the preceding EJB-JAR project.

Test class:

@RunWith(Arquillian.class)
public class EarIT {

    @Deployment
    public static Archive<?> createDeploymentPackage() throws IOException {
        final JavaArchive ejbJar = ShrinkWrap.create(JavaArchive.class, "ejb-jar.jar").addClass(SomeEjb.class);

        // Embedding war package which contains the test class is needed
        // So that Arquillian can invoke test class through its servlet test runner
        final WebArchive testWar = ShrinkWrap.create(WebArchive.class, "test.war").addClass(EarIT.class);
        final EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class)
                .setApplicationXML("test-application.xml")
                .addAsModule(ejbJar)
                .addAsModule(testWar);
        return ear;
    }

    @EJB
    private SomeEjb someEjb;

    @Test
    public void test() {
        Assert.assertEquals("Hello, Kyle", someEjb.hello("Kyle"));
    }
}

test-application.xml which will be embed as application.xml:

<application>
    <display-name>ear</display-name>
    <module>
        <ejb>ejb-jar.jar</ejb>
    </module>
    <module>
        <web>
            <web-uri>test.war</web-uri>
            <context-root>/test</context-root>
        </web>
    </module>
</application>

Also I have an another example that uses the EAR which Maven has produced because creating EAR with ShrinkWrap would be annoying in some complex cases. the @Deployment method will embed the test WAR into the EAR, and add a module element into existing application.xml before returning the archive to Arquillian runtime. the @Deployment method would be something like this:

...
@Deployment
public static Archive<?> createDeploymentPackage() throws IOException {
    final String testWarName = "test.war";

    final EnterpriseArchive ear = ShrinkWrap.createFromZipFile(
            EnterpriseArchive.class, new File("target/ear-1.0-SNAPSHOT.ear"));

    addTestWar(ear, EarFromZipFileIT.class, testWarName);
...


Arquillian Persistence Extension examples


Posted on Wednesday Mar 18, 2015 at 05:47PM in Arquillian


The whole project can be obtained from GitHub. tested with WildFly 8.2.0.Final as remote container.

Implementation (test target)

Assume we have very simple 2 entities as follows:

@Entity
public class Dept implements Serializable {
    @Id
    private Integer id;
    @Column(nullable = false)
    private String name;
    @OneToMany(mappedBy = "dept")
    private Collection<Employee> employees;
...

@Entity
public class Employee implements Serializable {
    @Id
    private Integer id;
    @Column(nullable = false)
    private String name;
    @JoinColumn(nullable = false)
    @ManyToOne
    private Dept dept;
...

Test target EJB:

@Stateless
@LocalBean
public class HumanResourcesBean {

    @PersistenceContext
    private EntityManager em;

    public void addEmployee(Employee employee, Integer deptId) {
        final Dept dept = em.find(Dept.class, deptId);
        dept.getEmployees().add(employee);
        employee.setDept(dept);
        em.persist(employee);
    }

    public void addDept(Dept dept, Employee employee) {
        Collection<Employee> employees = new ArrayList<>();
        dept.setEmployees(employees);
        employees.add(employee);
        employee.setDept(dept);
        em.persist(dept);
        em.persist(employee);
    }
}

addEmployee() testing

Test method of addEmployee():

@Test
@UsingDataSet("input.xml")
@ShouldMatchDataSet(value = "addEmployee-expected.xml", orderBy = "id")
public void addEmployeeTest() throws Exception {
    Employee emp = new Employee();
    emp.setId(2002);
    emp.setName("Todd");
    humanResourcesBean.addEmployee(emp, 200);
}

Initial entry data (input.xml):

<dataset>
    <Dept id="100" name="Sales"/>
    <Dept id="200" name="Finance"/>
    <Employee id="1000" name="Scott"  dept_id="100"/>
    <Employee id="1001" name="Martin" dept_id="100"/>
    <Employee id="1002" name="Nick"   dept_id="100"/>
    <Employee id="2000" name="Jordan" dept_id="200"/>
    <Employee id="2001" name="David"  dept_id="200"/>
</dataset>

Expected data (addEmployee-expected.xml):

<dataset>
    <Employee id="1000" name="Scott"  dept_id="100"/>
    <Employee id="1001" name="Martin" dept_id="100"/>
    <Employee id="1002" name="Nick"   dept_id="100"/>
    <Employee id="2000" name="Jordan" dept_id="200"/>
    <Employee id="2001" name="David"  dept_id="200"/>
    <Employee id="2002" name="Todd"   dept_id="200"/> <!-- Newly added -->
</dataset>

addDept() testing

Test method of addDept():

@Test
@UsingDataSet("input.xml")
@ShouldMatchDataSet(value = "addDept-expected.xml", orderBy = "id")
public void addDeptTest() throws Exception {
    Dept dept = new Dept();
    dept.setId(300);
    dept.setName("Engineering");
    Employee emp = new Employee();
    emp.setId(3000);
    emp.setName("Carl");
    humanResourcesBean.addDept(dept, emp);
}

Initial entry data (input.xml) is the same to previous testing.

Expected data (addDept-expected.xml):

<dataset>
    <Dept id="100" name="Sales"/>
    <Dept id="200" name="Finance"/>
    <Dept id="300" name="Engineering"/> <!-- Newly added -->
    <Employee id="1000" name="Scott"  dept_id="100"/>
    <Employee id="1001" name="Martin" dept_id="100"/>
    <Employee id="1002" name="Nick"   dept_id="100"/>
    <Employee id="2000" name="Jordan" dept_id="200"/>
    <Employee id="2001" name="David"  dept_id="200"/>
    <Employee id="3000" name="Carl"   dept_id="300"/> <!-- Newly added -->
</dataset>

It works well with multiple tables.

addDept() testing with DBUnit

Sometimes use of DBUnit directly is useful for complex assertion. in such case you need to care following conditions:

  • If you use JPA, force EntityManager to execute DMLs via invoking em.flush() before assertion

  • Include test data to the Arquillian’s application archive so that DBUnit can load these data on the server side

The XML can be included via addAsResource() method as follows:

@Deployment
public static Archive<?> createDeploymentPackage() {
    final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
            .addPackage(Dept.class.getPackage())
            .addClass(HumanResourcesBean.class)
            .addAsResource("datasets/addDept-expected.xml") // to be loaded by DBUnit on the server side
            .addAsResource("test-persistence.xml", "META-INF/persistence.xml");
//        System.out.println(webArchive.toString(true));
    return webArchive;
}

The test method of addDept() and related convenient methods:

@Test
@UsingDataSet("input.xml")
public void addDeptTestWithDbUnit() throws Exception {
    Dept dept = new Dept();
    dept.setId(300);
    dept.setName("Engineering");
    Employee emp = new Employee();
    emp.setId(3000);
    emp.setName("Carl");

    humanResourcesBean.addDept(dept, emp);
    em.flush(); // force JPA to execute DMLs before assertion

    final IDataSet expectedDataSet = getDataSet("/datasets/addDept-expected.xml");
    assertTable(expectedDataSet.getTable("Dept"), "select * from dept order by id");
    assertTable(expectedDataSet.getTable("Employee"), "select * from employee order by id");
}

private static IDataSet getDataSet(String path) throws DataSetException {
    return new FlatXmlDataSetBuilder().build(HumanResourcesBeanIT.class.getResource(path));
}

private void assertTable(ITable expectedTable, String sql) throws SQLException, DatabaseUnitException {
    try (Connection cn = ds.getConnection()) {
        IDatabaseConnection icn = null;
        try {
            icn = new DatabaseConnection(cn);
            final ITable queryTable = icn.createQueryTable(expectedTable.getTableMetaData().getTableName(), sql);
            Assertion.assertEquals(expectedTable, queryTable);
        } finally {
            if (icn != null) {
                icn.close();
            }
        }
    }
}