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 } }