When testing a EE application you regularly rely on EJBContainer.
One issue is its lifecycle handling. Most of implementations map it (and that’s really correct) to the test lifecycle. In summary it looks like:
@BeforeClass public static void boot() { container = EJBContainer.createEJBContainer(); } @AfterClass public static void shutdown() { container.close(); }
That’s what does openejb-junit too when you use EJBContainerRule.
It is great but when having a lot of tests starting/stopping the container for each test can be time consuming compared to the test duration.
If each test uses the same config just start the container/app once and run your tests.
To do it with OpenEJB just add in container properties the following property (available from coming 4.7.0 version):
openejb.ejbcontainer.close = single-jvm
This will basically prevent container.close() to close the container and register a shutdown hook on the JVM to call it.
The drawback doing it is it breaks the ability of OpenEJB to inject beans/resources in the tests which didn’t boot the container.
To solve it just decorate your tests with @ManagedBean.
Here what a test can look like using openejb-junit module:
@ManagedBean @Properties( @Property( key = OpenEjbContainer.OPENEJB_EJBCONTAINER_CLOSE, value = OpenEjbContainer.OPENEJB_EJBCONTAINER_CLOSE_SINGLE)) public class Bean1Test { @ClassRule // or just @Rule to pass test instance to the constructor and avoid to call inject(this) public static final EJBContainerRule r = new EJBContainerRule(); @Inject private Bean bean; @Test public void a() { r.inject(this); assertEquals("bean", bean.name()); } }
Side note: in this case the properties shouldn’t be on the test class since they will be shared accross all tests but in surefire for instance.
Nice, giving users greater control.
Alternatively: Arquillian starts the container at the suite boundary, not the test boundary. So startup/shutdown would be once.
S,
ALR
Yes, only issue (and why we still enhance EJBContainer) is the fact arquillian is often not what users look for for simple setups, they just want to deploy their classpath (auto @Deployment) + there is a big difference here: no deployment by test but a single one ;). So basically tests doesn’t touch the container from the second class to the end.