| JdbcAndTransactionTest.java |
package org.mockejb.test;
import java.util.Collection;
import javax.naming.*;
import com.mockrunner.mock.ejb.MockUserTransaction;
import org.mockejb.*;
import org.mockejb.jndi.*;
import org.mockejb.interceptor.*;
/**
* Demonstrates the use of JDBC and transactions with MockEJB.
*
* @author Alexander Ananiev
*/
public class JdbcAndTransactionTest extends OptionalCactusTestCase {
// State of this test case. These variables are initialized by setUp method
private SampleService sampleService;
private SampleServiceHome sampleServiceHome;
private Context context;
// Aspect system used by this test
private AspectSystem aspectSystem;
private MockUserTransaction mockTransaction;
/**
* Constructor for JdbcTransactionTest.
* @param name name of the test
*/
public JdbcAndTransactionTest(String name) {
super(name);
}
/**
* Deploys and creates EJBs needed for our tests.
*/
public void setUp() throws Exception {
aspectSystem = AspectSystemFactory.getAspectSystem();
// inside the app server use its InitialContext
if ( isRunningOnServer() ) {
context = new InitialContext( );
}
// if the test runs outside of the app server
else {
MockContextFactory.setAsInitial();
// create the initial context that will be used for binding EJBs
context = new InitialContext( );
// Create an instance of the MockContainer
MockContainer mockContainer = new MockContainer( context );
/* Create deployment descriptor of our sample bean.
* MockEjb does not support XML descriptors.
*/
SessionBeanDescriptor sampleBeanDescriptor =
new SessionBeanDescriptor( SampleService.JNDI_NAME,
SampleServiceHome.class, SampleService.class, SampleServiceBean.class );
// Deploy operation simply creates Home and binds it to JNDI
mockContainer.deploy( sampleBeanDescriptor );
// StatelssSampleBean calls SampleHelperBean, so we need to deploy it too
SessionBeanDescriptor helperBeanDescriptor =
new SessionBeanDescriptor( SampleServiceBean.HELPER_BEAN_JNDI_NAME,
SampleHelperHome.class, SampleHelper.class, SampleHelperBean.class );
mockContainer.deploy( helperBeanDescriptor );
/* Prepare the data source if we are not running in the app server.
* We assume that the app server has the data source pre-configured.
* You don't have to do it that way, the code will work in both cases,
* however it is "cleaner" to rely on the infrastructure provided by the
* app server for in-container testing. Also, the data source inside the
* app server may point to a completely different database.
*/
// Instantiate DataSource implementation
// You can use Jakarta DBCP
//org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
//ds.setDriverClassName("com.mysql.jdbc.Driver");
// You can also use DataSource implementation that comes with MySQL driver
com.mysql.jdbc.jdbc2.optional.MysqlDataSource ds = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
// Or, in case of Oracle driver:
// oracle.jdbc.pool.OracleDataSource ds = oracle.jdbc.pool.OracleDataSource();
// point to the database - we use the default MySql database.
ds.setUrl("jdbc:mysql://localhost:3306/test");
// add to the context
context.rebind("java:comp/env/jdbc/SampleDataSource", ds);
// we use MockTransaction outside of the app server
mockTransaction = new MockUserTransaction();
context.rebind("javax.transaction.UserTransaction", mockTransaction );
}
// All EJBs are now deployed
// To get the Sample bean we use the standard J2EE routine
// Lookup the home
SampleServiceHome sampleHome = (SampleServiceHome)context.lookup( SampleService.JNDI_NAME );
// create the bean
sampleService = sampleHome.create();
}
/**
* Performs the necessary cleanup by restoring the system properties that
* were modified by MockContextFactory.setAsInitial().
* This is needed in case if the test runs inside the container, so it would
* not affect the tests that run after it.
*/
public void tearDown() {
MockContextFactory.revertSetAsInitial();
}
/**
* Tests EJB interaction with the database without transactions, i.e,
* the transactional policy is "Suppports".
*/
public void testJdbc() throws Exception {
/* Read something from the database
* We assume the existence of the "test_table" with a column "name".
*/
Collection values = sampleService.selectFromTable( "test_table", "name");
assertNotNull(values);
}
/**
* Demonstrates the use of transactions with MockEJB.
* Outside of the container, we use MockTransaction, inside we can rely on
* the real transaction support. Inside the container we can't really test much.
*/
public void testTransactions() throws Exception {
// it does not make sense to run this test on the server since we can't test much
if ( isRunningOnServer() ){
return;
}
// set our policy
aspectSystem.add( new ClassPatternPointcut("org.mockejb.test"),
new TransactionManager( TransactionPolicy.REQUIRED ));
Collection values = sampleService.selectFromTable( "test_table", "name");
assertNotNull(values);
assertTrue( mockTransaction.wasBeginCalled() );
assertTrue( mockTransaction.wasCommitCalled() );
// Call the method that explicitly rolls back the transaction using ejb context
mockTransaction.reset();
sampleService.rollbackSampleTransaction();
assertTrue( mockTransaction.wasBeginCalled() );
assertTrue( mockTransaction.wasRollbackOnlyCalled() );
assertTrue( mockTransaction.wasRollbackCalled() );
// TODO: test other policies
}
}