Version 4

    (written by germanescobar)

     

    Here is how I used Arquillian to test a simple JMX Portable Extension that I wrote a few weeks ago. The extension allows you to automatically register MBeans using annotations. For example:

     

     

    @ApplicationScoped
    @MBean("org.gescobar:type=VisitorCounter")
    @Description("Counts the number of visits")
    public class VisitorCounter {  
      
      @ManagedAttribute(readable=true,writable=true)  
      private int counter;  
      
      public void addVisitor() {    
        counter++;  
      }  
    
      @ManagedOperation(impact=Impact.ACTION)  
      public void resetCounter() {    
        counter = 0;  
      }  
    
      // getter and setters
    }

     

     

    When the bean is instantiated, it will be automatically registered as an MBean on an MBeanServer. You can check my full post on this extension here.

     

    After I finished writing the extension, I needed a way of testing it on different containers. So, I decided to try Arquillian.

     

    First, I added TestNG and Arquillian dependencies to my pom.xml file (I could also have used JUnit):

     

      ...
      <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>5.10</version>
        <classifier>jdk15</classifier>
        <scope>test</scope>
      </dependency>
    
      <dependency>
        <groupId>org.jboss.arquillian</groupId>
        <artifactId>arquillian-testng</artifactId>
        <version>1.0.0.Alpha1</version>
        <scope>test</scope>
      </dependency>
      ...
    

     

    Then, I created two profiles on my pom.xml: one for JBoss AS 6.0.0.M2 and other for the Weld-SE (testing inside other containers is just a matter of creating more profiles):

     

      <profiles>
        <profile>
          <id>jbossas-remote-60</id>
          <dependencies>
            <dependency>
              <groupId>org.jboss.arquillian.container</groupId>
             <artifactId>arquillian-jbossas-remote-60</artifactId>
             <version>1.0.0.Alpha1</version>
            </dependency>
          </dependencies>
        </profile>
        <profile>
          <id>weld-embedded</id>
          <dependencies>
            <dependency>
             <groupId>org.jboss.arquillian.container</groupId>
             <artifactId>arquillian-weld-embedded</artifactId>
             <version>1.0.0.Alpha1</version>
            </dependency>
          </dependencies>
        </profile>
      </profiles>

     

    Finally, I wrote my test class. The only two things you need to add to your regular TestNG class are:

     

    1. The class must extend org.jboss.arquillian.testng.Arquillian.
    2. Create a method annotated with @Deployment that returns a Shrinwrap Archive.

     

    public class TestAutoRegistration extends Arquillian { 
    
        @Deployment
        public static JavaArchive createDeployment() {
         
         JavaArchive archive = Archives.create("test.jar", JavaArchive.class)
              .addPackage(MBeanFactory.class.getPackage()) 
              .addPackage(CDIMBeanFactory.class.getPackage())
              .addPackage(MBeanServerLocator.class.getPackage())
              .addClasses(CounterAutoRegisterWithName.class, CounterAutoRegisterNoName.class)
              .addManifestResource("services/javax.enterprise.inject.spi.Extension")
              .addManifestResource(
                   new ByteArrayAsset("<beans/>".getBytes()), 
                              Paths.create("beans.xml"));
         
         return archive;
        }
    
        @Inject
        private CounterAutoRegisterWithName counterWithName;
    
        @Inject
        private CounterAutoRegisterNoName counterNoName;
    
        @Test
        public void shouldRegisterAnnotatedWithNameMBean() throws Exception {
         Assert.assertNotNull(counterWithName);
         
         // the bean is not created until the first call - maybe a bug in weld?
         Assert.assertEquals(counterWithName.getCounter(), 0);
         
         MBeanServer mBeanServer = MBeanServerLocator.instance().getmBeanServer();
         ObjectName name = new ObjectName("org.gescobar:type=CounterAutoRegisterWithName");
         
         // check we can add the counter
         mBeanServer.setAttribute(name, new Attribute("counter", 1));
         Assert.assertEquals(counterWithName.getCounter(), 1);
         
         // check we can retrieve the counter
         Integer result = (Integer) mBeanServer.getAttribute(name, "counter");
         Assert.assertNotNull(result);
         
         // check we can call method without arguments
         mBeanServer.invoke(name, "resetCounter", null, null);
         Assert.assertEquals(counterWithName.getCounter(), 0);
         
         // check we can call method with arguments
         mBeanServer.invoke(name, "resetCounter2", new Object[] { 5 }, new String[] { "java.lang.Integer" });
         Assert.assertEquals(counterWithName.getCounter(), 5);
        }
    
        @Test
        public void shouldRegisterAnnotatedWithNoNameMBean() throws Exception {
         Assert.assertNotNull(counterNoName);
         
         Assert.assertEquals(counterNoName.getCounter(), 0);
         
         MBeanServer mBeanServer = MBeanServerLocator.instance().getmBeanServer();
         Object result = mBeanServer.getAttribute(new ObjectName("org.gescobar.management.test:type=CounterAutoRegisterNoName"), "counter");
         
         Assert.assertNotNull(result);
        }
    }
    

     

    Now, to run the tests, I just have to call the appropiate profile:

    • mvn clean install -Pjbossas-remote-60
    • mvn clean install -Pweld-embedded

     

    Note: JBoss AS 6.0.0.M2 must be running if you are using the -Pjbossas-remote-60 profile. Arquillian does not start/stop the container automatically ... yet!

     

    As you can see, it was really easy to add Arquillian support to my project and now I can test my extension on real containers!


    This article was generated from the following thread: Testing a JMX Portable Extension for CDI