package org.testfun.jee; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runner.manipulation.Filter; import org.junit.runner.manipulation.Filterable; import org.junit.runner.manipulation.NoTestsRemainException; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.InitializationError; import org.mockito.MockitoAnnotations; import org.mockito.internal.runners.util.FrameworkUsageValidator; import org.testfun.jee.runner.DependencyInjector; import org.testfun.jee.runner.inject.TransactionUtils; import java.lang.reflect.InvocationTargetException; /** * A JUnit runner that allows injection of JEE EJBs as well as Mockito mock objects directly into the test instance. * <p> * To use this runner, simply annotate the test class with * <pre>{@code @RunWith(EjbWithMockitoRunner.class) }</pre> */ public class EjbWithMockitoRunner extends Runner implements Filterable { private BlockJUnit4ClassRunner runner; public EjbWithMockitoRunner(Class<?> klass) throws InvocationTargetException, InitializationError { runner = new BlockJUnit4ClassRunner(klass) { @Override protected Object createTest() throws Exception { Object test = super.createTest(); // init annotated mocks before tests MockitoAnnotations.initMocks(test); // inject annotated EJBs before tests injectEjbs(test); // Rollback any existing transaction before starting a new one TransactionUtils.rollbackTransaction(); TransactionUtils.endTransaction(true); // Start a new transaction TransactionUtils.beginTransaction(); return test; } }; } public void run(RunNotifier notifier) { // add listener that validates framework usage at the end of each test notifier.addListener(new FrameworkUsageValidator(notifier)); runner.run(notifier); } public Description getDescription() { return runner.getDescription(); } public void filter(Filter filter) throws NoTestsRemainException { runner.filter(filter); } private void injectEjbs(Object target) { DependencyInjector.getInstance().reset(); DependencyInjector.getInstance().injectDependencies(target); } }