Seam 3 JMS Module Testing with Arquillian

Overview

As development begins on the Seam 3 JMS Module, Aquillian has already made it very easy to verify the early functionality. This article explains how Arquillian has been used to demonstrate that injection of JMS resources and forwarding CDI events to JMS works correctly.

 

Injection Testing

In order to test injection of JMS resources, those resources must be available. That means testing in the container, Arquillian's mantra!

 

For now, all tests are set up using the Arquillian jboss-remote-60 profile, allowing us to test on a running instance of JBoss AS 6.0. Our initial tests use JUnit 4 and assume JBoss messaging is installed as the JMS provider.  While temporary topics can be created programatically, I wanted to additionally test the deployment of JBoss Messaging destinations through Arquillian. JBoss Messaging allows deployment descriptors for destinations to be bundled with deployments, allowing us to set up this test case for JMS resource injection entirely within Arquillian.

 

In order to test simple destination injection we need to set up the ShrinkWrap deployment archive to include the JMS portable extension, required classes, and the configuration for the topic destination:

 

@RunWith(Arquillian.class)
public class JmsResourceInjectionTest {
   @Deployment
   public static Archive<?> createTestDeployment()
   {
      return Archives.create("test.jar", JavaArchive.class)
         .addPackages(false, Seam3JmsExtension.class.getPackage(), SimpleInjectionTest.class.getPackage())
         .addManifestResource(new ByteArrayAsset(new byte[0]), ArchivePaths.create("beans.xml"))
         // Register the portable extension 
         .addServiceProvider(Extension.class, Seam3JmsExtension.class) 
         // Include JBoss Messaging topic configuration
        .addManifestResource("topic_T-service.xml");
   }
}

 

Here's the topic destination configuration, topic_T-service.xml:

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<server>
   <mbean xmbean-dd="xmdesc/Topic-xmbean.xml"
   name="jboss.messaging.destination:service=Topic,name=T"
   code="org.jboss.jms.server.destination.TopicService">
      <attribute name="JNDIName">jms/T</attribute>
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends>jboss.messaging:service=PostOffice</depends>
   </mbean>
</server>

 

 

With the deployment set up to register our portable extension and resources, we can now test injection of a topic directly into the test class.

 

@Inject Topic t;

@Test
public void simpleTopicInjection()
{
    assertNotNull(t);
    assertEquals("T", t.getTopicName());
}

 

The injection point is satisfied by a Topic producer method, which takes the name of the field, captializes it, appends it to the string "/jms/" and looks up the name (in this case /jms/T) in the JNDI InitialContext.

 

Bridged Events

Where Arquillian has really begun to show its potential is when testing CDI events bridged to JMS. To provide some background, the Seam 3 JMS module will provide support for declaratively forwarding events over JMS.  While there are a few components involved in making this work, let's take a look at one of the test cases that verifies the events are being forwarded to their proper destination.

 

We must be able to identify when messages are sent over JMS.  To do this we use a MessageConsumer and a simple test event.

 

@Inject Connection c;
@Inject Session s;
@Inject @Events Topic t;
@Inject Seam3JmsExtension jmsExt;
@Inject Event<String> event;

 

The test case requires that we register our event type to be forwarded over JMS, create a MessageConsumer to consume events from the intended destination, fire the event and check if we received it over the destination:

 

@Test(timeout=5000)
public void forwardEvent() throws Exception
{
   String expected = "test";
   jmsExt.register(String.class, t);
   MessageConsumer mc = s.createConsumer(t);
   c.start();
   event.fire(expected);
   Message m = mc.receive();
   assertNotNull(m);
   assertTrue(m instanceof ObjectMessage);
   assertEquals(expected, ((ObjectMessage) m).getObject());
}

 

You can read more about CDI events in the Weld reference documentation.

 

What's Next

We've taken a look into how Arquillian is making it possible to rapidly test the initial development efforts toward creating the Seam 3 JMS module.  As more functionality is built, more tests will be written, so look to this module as a source of ideas for how to use Arquillian.

 

One of the features I'm looking forward to in Arquillian is the ability to include additional libraries in the test deployments. Hopefully that gets fixed soon! http://jira.jboss.org/jira/browse/ARQ-66.

 

Stay tuned for more developments on Seam 3 at http://www.seamframework.org and keep watching the Arquillian of the announcement for the Alpha1 release!