Having richer tests with Arquillian

Let’s add an auditing feature to the previous post‘s example. As simple as writing into a log file everything that went through the save business method in the employees’ service. To do so, we need to add an appender to the jboss-log4j.xml file, code an interceptor and register it with the method.

To test this interceptor class is doing its job you need to access the audit.log file, something inside the application server. I t means it’s necessary to enrich the test case with a reference to this file. In Arquillian, test enrichmentmeans hooking the test class to the container environment by satisfying its injection points“. What we are going to inject into the test class is the log file so we can check it’s growing up with the logs from the interceptor.

Code

log-enricher.tar and lunch-ejb-enriched.tar

Building the test enricher

In order to build our test enricher we need to code a marker for the injection point

public @interface TargetLog

Get a reference to the log file and inject it to in the marked class member. This is the actual enrichment process, the service provider, so this is an implementation of the org.jboss.arquillian.spi.TestEnricher interface

public class LogEnricher implements TestEnricher
...
public void enrich(Context context, Object testCase) {
if (jbossHome == null && jbossHome.isEmpty()) {
throw new RuntimeException("Set your JBOSS_HOME variable.");
}
Field target = findTargetField(testCase.getClass());
if (target != null) {
injectLogFile(testCase, target);
}
}

Then pack the test enricher inside an implementation of org.jboss.arquillian.spi.AuxiliaryArchiveAppender

public class LogPackager implements AuxiliaryArchiveAppender

and finally make the LogPackager  an available service by registering it inside resources/META-INF/services/org.jboss.arquillian.spi.AuxiliaryArchiveAppender

Using the test enricher

Copy the resources/META-INF/services/org.jboss.arquillian.spi.AuxiliaryArchiveAppender file insider the test resources.

Add a test scoped dependency on the test enricher

<dependency>
<groupId>ec.pazmino</groupId>
<artifactId>log-enricher</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>

Set where the log is going to be injected

@TargetLog(name = "audit.log")
private File auditLog;

include in the deployment method the marker class and the service provider contract and implementation

archive.addClasses(TargetLog.class);
archive.addServiceProvider(TestEnricher.class, LogEnricher.class);

code the test.

@Test(expected = UniqueFieldException.class)
public void testLogGrows() throws SQLException {
assertNotNull("Service wasn't injected. ", employeeService);
assertNotNull("audit.log wasn't injected", auditLog);
Assert.assertTrue("The log file doesn't exist", auditLog.exists());
long logSize = auditLog.length();
Employee employee = new Employee();
employee.setUsername("iapazmino");
employee = employeeService.save(employee);
Assert.assertTrue("New lines were not writen", auditLog.length() > logSize);
}

Now you can write a test enricher for real.

Advertisements

3 responses to “Having richer tests with Arquillian

  1. front page feed again!

    If you place the TargetLog, LogEnricher, LogPackager and the AuxiliaryArchiveAppender SPI registration all inside the log-enricher.jar, you don’t have to do anything on the user side besides adding the dependency to the classpath.

    log-enricher.jar:

    TargetLog.class

    LogEnricher.class

    LogPackager.class

    -aslak-

  2. front page feed again!

    If you place the TargetLog, LogEnricher, LogPackager and the AuxiliaryArchiveAppender SPI registration all inside the log-enricher.jar, you don’t have to do anything on the user side besides adding the dependency to the classpath.

    log-enricher.jar:

    – LogEnricher user facing API

    TargetLog.class

    – TestEnricher impl

    LogEnricher.class

    – Client side packager for making a archive deployment that will be auto included in the users deployment.
    Implements the AuxiliaryArchiveAppender SPI. Responsible for packaging up the Enricher so it can be executed inside the container, including needed classes and SPI registration.

    LogPackager.class

    -aslak-

    (sorry, lost the comments in the firstreply)

  3. great post, thanks for sharing

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