If you really only want to test the JPA entities, and don't mind the transactions, why not remove the @Stateless and @EJB completely, and just make your test @LocalClient and inject an entity manager?
If this is not the case, why exactly do you need the JTA? In this case just split up the test case and the EJB. That double injections of the entity manager and EJB seems ugly. Quintin Beukes On Fri, Oct 2, 2009 at 7:20 PM, Laird Nelson <ljnel...@gmail.com> wrote: > This falls under the category of interesting hacks. It also falls under the > category of "the goggles...they do nothing!". But it's Friday. > > So I'm unit testing, and wanted to use OpenEJB's ability to run an SLSB in a > transaction really only for the fact that that SLSB could then use an > injected, transactional EntityManager without hassle. > > That is, really the thing I want to test is my JPA machinery--the mappings, > the validations, etc. The easiest way to make this happen is to test an > insert and retrieval with an EntityManager, and the easiest way to get an > entity manager is to have one injected into a stateless session bean so you > don't have to manage all the transactions for yourself. But I'm in unit > test mode--I don't really want to create an SLSB and a TestCase for every > stupid JPA scenario I want to test. Ideally I would {handwave handwave} > have a transactional entity manager injected into my test case for me > somehow but {handwave handwave} run as part of the EJB container {more > handwaving}. But my test case is not an EJB. It is at the moment only a > @LocalClient. > > Well, so, I made my TestCase both a @Stateless and a @LocalClient. :-) It > implements a simple interface that basically defines what methods I want to > have exposed through the local business interface. Ideally even this step > wouldn't be necessary--once you can have an interfaceless SLSB in EJB 3.1, > you can throw this step out. > > I annotate my test methods with @Test (from JUnit). I inject my @EJB (the > test case itself!) into...uh...itself. :-) I also inject an > EntityManager. Unfortunately the EntityManager shows up both "in" the > test-case-as-EJB and the test-case-as-LocalClient. I just take care not to > use it in the test-case-as-LocalClient methods. There is probably a way in > @Before to null it out in such a case; I'll do that next. > > Anyhow, the net effect is that I can use an injected EntityManager in my > test case which is effectively wrapped in itself as a SLSB. That's the part > that makes my eyes go funny. Anyhow, it makes in-memory JPA testing pretty > painless. > > The whole thing looks like this (the abstract test case I'm inheriting from > does the OpenEJB initialization, but not much else; the code below is > condensed for brevity): > > import javax.ejb.*; > import javax.persistence.*; > import org.junit.Test; > import junit.openejb.AbstractOpenEJBTestCase; > import org.apache.openejb.api.LocalClient; > import static org.junit.Assert.*; > > @Stateless @LocalClient > public class TestCaseXY extends AbstractOpenEJBTestCase implements > TestClient { > > �...@ejb private TestClient tc; // a reference to...um...myself > �...@persistencecontext private EntityManager em; > > // The JUnit test method. Don't use the EntityManager here; > // I think its behavior would be undefined since your > // persistence.xml should be designating a JTA data source, > // but you're not in a JTA context here. > �...@test public final void testXYClient() { > assertNotNull(this.tc); > this.tc.testXY(); // "Forward" to the "real" test method. > } > > // The "real" test method. Run in a transaction, with EJB security, etc. > �...@override public void testXY() { > assertNotNull(this.em); > assertNotNull(this.tc); > assertNotSame(this.tc, this); > // Actual test code goes here > } > > } > > // Interestingly, this doesn't have to be public so you can put it in the > same file. > interface TestClient { > public void testXY(); > } > > I hope someone finds this useful; feel free to get in touch (ell jay nelson > at gee mayul dot com) if you have questions. > > Best, > Laird >