Archive

Posts Tagged ‘junit’

Using Embedded JBoss for functional flow testing for EJB3

June 21st, 2010 Shrihari No comments

From the past few days, I have been trying to evaluate various mechanisms to acheive functional flow testing for a runtime EAR deployable. Under the assumption that the final deployment will be on JBOSS-AS-5.1.x, our goal is to chalk out a testing environment thats close to the actual deployed environment.

Various mechanisms for setting up the environment surfaced.

  • Deploying EAR using Maven-Cargo-Plugin (jboss51x) including options to start jboss (pre-integration-test) and stop jboss(post-integration-test) and perform integration tests.
  • Using Embedded JBOSS to start/stop the container pre/post test-case execution and deploy the EAR.
  • Using OpenEJB, an embeddable and lightweight EJB 3.0 Implementation container environment.
  • Using Arquillian(framework to perform integration test) and Shrinkwrap(framework to create JAR/WAR/EAR archive dynamically) APIs from JBOSS

In this edition of the write-up, I would like to focus on the preparing a deployable for Embedded JBOSS, for an example flow. Lets consider
a naive shopping cart example which would given a list of items (with valid item codes), would persist the cart details, generate an invoice
amount. Following are the stateless bean interface and implementation in EJB3 semantics:

package shoppingcart;
import javax.ejb.Local;

@Local
public interface ShoppingCart
{   public Double generateInvoice(List items,String coupon) throws InvalidCartException;
}

Assuming isCouponValid() and getDiscount()/addTax are functional stubs implemented appropriately, following is the bean code.

package shoppingcart;
import javax.ejb.Stateless;
import javax.jpa.PersistenceContext;

@Stateless
public class ShoppingCartBean implements ShoppingCart
{   @PersistenceContext EntityManager em;

public Double generateInvoice(List items,String coupon) throws InvalidCartException
{  if(items.size() <= 0)
throw new InvalidCartException("No items present in the shopping cart!");
if(isCouponValid(coupon))
throw new InvalidCartException("Shopping cart's Coupon Code is not valid!");
Double totalPrice = 0;
for(Item item:items)
{   totalPrice += (item.getQuantity()*item.getPrice()));
}
totalPrice -= getDiscount(coupon);
totalPrice += addTax(totalPrice);
return totalPrice;
}
}

Use the Maven configuration for Embedded JBoss, we could set up the necessary environment for implementing the test cases. Following are the additional changes:
1) If you have a datasource file, copy it under test/resources/deploy.
2) Copy persistence.xml under test/resources/META-INF.

Once done. here is the JUnit code to test the functional flow for shopping cart

package shoppingcarttest;

import org.jboss.bootstrap.spi.Bootstrap;
import org.jboss.deployers.spi.DeploymentException;
//other imports..

public class ShoppingCartTest
{  @BeforeClass
public static void startup() {
try {
if (!Bootstrap.getInstance().isStarted()) {
Bootstrap.getInstance().bootstrap();
}
deploy();
} catch (DeploymentException deploy) {
deploy.printStackTrace();
}
}

private static void deploy() {
Bootstrap bootstrap = Bootstrap.getInstance();
try
{    bootstrap.deployResourceBase(ShoppingCart.class);
bootstrap.deployResourceBases("META-INF/persistence.xml");
} catch (DeploymentException e)
{    throw new RuntimeException("Unable to deploy", e);
}
}

@Test
public void testShoppingCart()
{   InitialContext ctxt = new InitialContext();
ShoppingCart cart = (ShoppingCart)ctxt.lookup("ShoppingCartBean/local");
List items = new ArrayList(2);
items.add(new Item("Nokia E61",1));
items.add(new Item("Nokia E61 cable",1));
Double totalPrice = cart.generateInvoice(items, "XYZ123");
assertTrue(totalPrice > 0);
}

}

Using JBoss’s Bootstrap SPI, one can start the embedded container and deploy the EAR containing the enterprise-bean-under-test. We can also embrace TDD/BDD approach using mocks, er. Mockito