h1. Basic setup

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

h2. Business interface

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

h2. Bean Implementation(s)

{code}
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();
    }
}
{code}

h2. Have them discovered

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

h2. 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.

h1.  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.

{code}
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 as m");
        return query.getResultList();
    }
}

{code}

Test code below.

h2. Pure inlined

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

{code}
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;
            }
        });
    }
}
{code}

h2.  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.

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