Title: Unit Testing Transactions

<a name="UnitTestingTransactions-Basicsetup"></a>
# Basic setup

Add the following interface and bean to your test sources (they could even
be inner classes of a test case):

<a name="UnitTestingTransactions-Businessinterface"></a>
## Business interface


    public interface Caller {
        public <V> V call(Callable<V> callable) throws Exception;
    }


<a name="UnitTestingTransactions-BeanImplementation(s)"></a>
## Bean Implementation(s)


    import java.util.concurrent.Callable;
    
    @Stateless
    @TransactionAttribute(REQUIRES_NEW)
    public class TransactionBean implements Caller {
        public <V> V call(Callable<V> callable) throws Exception {
    	return callable.call();
        }
    }


<a name="UnitTestingTransactions-Havethemdiscovered"></a>
## Have them discovered

In src/test/resources/ (or related) create an META-INF/ejb-jar.xml
containing the text "<ejb-jar/>"

<a name="UnitTestingTransactions-Whatweaccomplished"></a>
## What we accomplished

Essentially what we've done is added an ejb that will be picked up as part
of your test code and deployed.  You can then look it up and use it to
execute test code with any particular transaction or security constraints
that you want.	The above bean specifies REQUIRES_NEW; functionally the
same as REQUIRED as the test case itself won't have a transaction, but a
little cleaner and more explicit.  

You could also annotate the bean with @RunAs("manager") for example and
test that your security restrictions are how you like them.  You can have
as many of these test beans in your test code as you like, each with it's
own transaction and security constraints allowing you to write some
incredibly thorough tests.

You do not need to use java.util.concurrent.Callable, any similar interface
of your creation could work just as well.  You may want something with
return type void, for example, to eliminate useless 'return null'
statements.

<a name="UnitTestingTransactions-Usage"></a>
#  Usage

There are a number of style choices for using the above bean, specifically
around the creation of the Callable object you pass in, and it all really
depends on what looks nice to you.

In the examples below, the Movies bean being tested is simply a thin layer
around JPA that allows us to use enforce various transaction semantics.


    import javax.ejb.Stateful;
    import javax.ejb.TransactionAttribute;
    import static javax.ejb.TransactionAttributeType.MANDATORY;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.PersistenceContextType;
    import javax.persistence.Query;
    import java.util.List;
    
    @Stateful(name = "Movies")
    @TransactionAttribute(MANDATORY)
    public class MoviesImpl implements Movies {
    
        @PersistenceContext(unitName = "movie-unit", type = PersistenceContextType.TRANSACTION)
        private EntityManager entityManager;
    
        public void addMovie(Movie movie) throws Exception {
    	entityManager.persist(movie);
        }
    
        public void deleteMovie(Movie movie) throws Exception {
    	entityManager.remove(movie);
        }
    
        public List<Movie> getMovies() throws Exception {
    	Query query = entityManager.createQuery("SELECT m from Movie asm");
        return query.getResultList();
        }
    }
    


Test code below.

<a name="UnitTestingTransactions-Pureinlined"></a>
## Pure inlined

The Callable can be created right in the test method itself.


    public class MoviesTest extends TestCase {
        private Context context;
    
        protected void setUp() throws Exception {
    	// initialize jndi context as usual
        }
    
        public void test() throws Exception {
    	Caller transactionBean = (Caller)
        context.lookup("TransactionBeanLocal");
    
    	transactionBean.call(new Callable() {
    	    public Object call() throws Exception {
    		Movies movies = (Movies) context.lookup("MoviesLocal");
    
    		movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
    		movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
    		movies.addMovie(new Movie("Joel Coen", "The Big Lebowski",1998));
    
    		List<Movie> list = movies.getMovies();
    		assertEquals("List.size()", 3, list.size());
    
    		for (Movie movie : list) {
    		    movies.deleteMovie(movie);
    		}
    
    		assertEquals("Movies.getMovies()", 0,movies.getMovies().size());
    
    		return null;
    	    }
    	});
        }
    }


<a name="UnitTestingTransactions-Sametestcode,differenttransactionscenarios"></a>
##  Same test code, different transaction scenarios

Maybe you'd like to test how things behave with and without a transaction
to guarantee everyone is doing the right thing in all situations.  Negative
testing is often a very good way to stomp out dangerous bugs.


    public class MoviesTest extends TestCase {
        private Context context;
    
        protected void setUp() throws Exception {
    	// initialize jndi context as usual
        }
    
        private void doWork() throws Exception {
    	      Movies movies = (Movies) context.lookup("MoviesLocal");
    
    	      movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs",1992));
              movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
    	      movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998));
    
    	      List<Movie> list = movies.getMovies();
    	      assertEquals("List.size()", 3, list.size());
    
    	      for (Movie movie : list) {
    	          movies.deleteMovie(movie);
    	      }
    
    	      assertEquals("Movies.getMovies()", 0, movies.getMovies().size());
        }
    
        public void testWithTransaction() throws Exception {
    	      Caller transactionBean = (Caller)context.lookup("TransactionBeanLocal");
    
    	      transactionBean.call(new Callable(){
    	            public Object call() throws Exception {
    		          doWork();
    		          return null;
    	            }
    	      });
        }
    
        public void testWithoutTransaction() throws Exception {
    	      try {
    	            doWork();
    	            fail("The Movies bean should be using TransactionAttributeType.MANDATORY");
    	      } catch (javax.transaction.TransactionRequiredException e) {
    	            // good, our Movies bean is using TransactionAttributeType.MANDATORY as we want
    	      }
        }
    }
