Testing

From Resin 3.0

(Difference between revisions)
Jump to: navigation, search
(CanDI/Resin Testing Support)
Line 6: Line 6:
  
 
public class AccountServiceTest {
 
public class AccountServiceTest {
 
 
   public static void main (String[] arguments) {
 
   public static void main (String[] arguments) {
 
     EmbeddedResin resin = new EmbedededResin();
 
     EmbeddedResin resin = new EmbedededResin();
 
 
     // Optional, is overriding default descriptor locations.
 
     // Optional, is overriding default descriptor locations.
 
     resin.addBeanXML("beans-test-1.xml, beans-test-2.xml");
 
     resin.addBeanXML("beans-test-1.xml, beans-test-2.xml");
Line 15: Line 13:
 
     resin.addPersistenceXML(
 
     resin.addPersistenceXML(
 
       "persistence-test-1.xml, persistence-test-2.xml");
 
       "persistence-test-1.xml, persistence-test-2.xml");
 
 
     resin.start(); // Detect currently running instances.
 
     resin.start(); // Detect currently running instances.
 
 
     AccountService accountService = resin.lookup(AccountService.class);
 
     AccountService accountService = resin.lookup(AccountService.class);
 
 
     resin.close(); // Optional.
 
     resin.close(); // Optional.
 
   }
 
   }
Line 29: Line 24:
  
 
@RunWith(ResinJUnitRunner.class)
 
@RunWith(ResinJUnitRunner.class)
@TestConfiguration(beanXML= �??beans-test.xml�??,
+
@TestConfiguration(beanXML="beans-test.xml",
                   ejbJar= �??ejb-jar-test.xml�??,   
+
                   ejbJar="ejb-jar-test.xml",   
                   persistenceXml=�??persistence-test.xml�??)
+
                   persistenceXml="persistence-test.xml")
 
public class AccountServiveTest {
 
public class AccountServiveTest {
 
 
   @Inject
 
   @Inject
 
   private AccountService accountService;
 
   private AccountService accountService;
 
 
   @Test
 
   @Test
 
   public void testGetAccount() throws Exception {
 
   public void testGetAccount() throws Exception {

Revision as of 00:16, 14 December 2009

CanDI/Resin Testing Support

We can provide very robust support for unit and integration testing via an embedded version of CanDI/Resin as well as specific APIs for JUnit and TestNG. In order to work with the usual usage pattern of JUnit and TestNG, both inside and outside an IDE, the embedded container will have to scan, detect and deploy exploded and unexploded modules in the classpath. We can do this by scanning the existence of annotations as well as deployment descriptors (beans.xml, ejb-jar.xml, application.xml, etc). We'll also need to scan for Resin deployment files in the classpath or in the file system.

In the most generic case, we should provide a simple bootstrap API for Java SE environments. This would be useful for newcomers to Resin as well as people who not use any test frameworks for testing. A simple use case could be something like this:

public class AccountServiceTest {

 public static void main (String[] arguments) {
   EmbeddedResin resin = new EmbedededResin();
   // Optional, is overriding default descriptor locations.
   resin.addBeanXML("beans-test-1.xml, beans-test-2.xml");
   resin.addEjbJarXML("ejb-jar-test-1.xml, ejb-jar-test-2.xml");      
   resin.addPersistenceXML(
     "persistence-test-1.xml, persistence-test-2.xml");
   resin.start(); // Detect currently running instances.
   AccountService accountService = resin.lookup(AccountService.class);
   resin.close(); // Optional.
 }

}

In the example above, we should add the capability to programmatically provide XML deployment descriptors to be used. This will enable developers provide test specific descriptors when needed (like test databases, mock objects, etc). By default, the embedded container can look for the default locations for descriptors in the classpath (e.g. META-INF/ejb-jar.xml, WEB-INF/ejb-jar.xml, META-INF/persistence.xml, etc). The start method should start the embedded container if it is not already running. This optimization would be useful while running a suite of tests. Lookup methods could be used to get reference to deployed components. The close method would shut-down an embedded container instance. It should be optional and only needed in the case where it is necessary to open and close containers in the same process. This essentially mirrors what is needed for the embeddable container API in EJB 3.1 Lite.

We can build on the basic Java SE based functionality and provide JUnit and TestNG specific support as below:

@RunWith(ResinJUnitRunner.class) @TestConfiguration(beanXML="beans-test.xml",

                  ejbJar="ejb-jar-test.xml",   
                  persistenceXml="persistence-test.xml")

public class AccountServiveTest {

 @Inject
 private AccountService accountService;
 @Test
 public void testGetAccount() throws Exception {
   Account account = accountService.getAccount(1007);
   assertNotNull(account);
 }

}

The JUnit/TestNG specific API can perform injection into the JUnit/TestNG class itself as well as manage the container life-cycle behind the scenes. This support mirrors what is provided for Spring testing support.

Building on the basic functionality, we can also put in integrated support for both EasyMock/JMock and DBUnit. For example, we could automatically mock all dependent objects and perform automatic DBUnit setup against any configured database. The following could also be useful:

1. Support explicitly listing files in the test so that only those files are loaded. 2. Excluding files from the test based on regular expressions patterns. 3. Allow selective disabling of Resin functionality for faster startup and shutdown. 4. Ant and Maven plugins that mirror the test API (perhaps used for continuous integration).

Seam allows for test scripts written against the web tier using JUnit/TestNG. I don�??t think we really need this since developers can easily use much better web tier testing tools like Selenium with the basic SE based functionality that is much more popular.

Personal tools