/* * Copyright 2010 - 2012 Toni Menzel, Harald Wellmann * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. * * See the License for the specific language governing permissions and * limitations under the License. */ package org.ops4j.pax.exam.junit.impl; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.InitializationError; import org.ops4j.pax.exam.spi.StagedExamReactor; import org.ops4j.pax.exam.spi.reactors.ReactorManager; import org.ops4j.pax.exam.util.InjectorFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Injecting runner for CDI tests. This runner does not use an invoker. * * @author Toni Menzel * @author Harald Wellmann */ public class InjectingRunner extends BlockJUnit4ClassRunner { private static final Logger LOG = LoggerFactory.getLogger(InjectingRunner.class); /** * Reactor manager singleton. */ private ReactorManager manager; /** * Staged reactor for this test class. This may actually be a reactor already staged for a * previous test class, depending on the reactor strategy. */ private StagedExamReactor stagedReactor; public InjectingRunner(Class<?> klass) throws InitializationError { super(klass); LOG.info("creating PaxExam runner for {}", klass); try { Object testClassInstance = klass.newInstance(); manager = ReactorManager.getInstance(); manager.prepareReactor(klass, testClassInstance); stagedReactor = manager.stageReactor(); } catch (InstantiationException | IllegalAccessException exc) { throw new InitializationError(exc); } } /** * We decorate the super method by reactor setup and teardown. This method is called once per * class. Note that the given reactor strategy decides whether or not the setup and teardown * actually happens at this level. */ @Override public void run(RunNotifier notifier) { LOG.info("running test class {}", getTestClass().getName()); Class<?> testClass = getTestClass().getJavaClass(); try { manager.beforeClass(stagedReactor, testClass); super.run(notifier); } // CHECKSTYLE:SKIP : catch all wanted catch (Throwable e) { // rethrowing the exception does not help, we have to use the notifier here Description description = Description.createSuiteDescription(testClass); notifier.fireTestFailure(new Failure(description, e)); } finally { manager.afterClass(stagedReactor, testClass); } } /** * Creates an instance of the current test class. When using a probe invoker, this simply * delegates to super. Otherwise, we perform injection on the instance created by the super * method. * <p> * In this case, an {@link InjectorFactory} is obtained via SPI lookup. */ @Override protected Object createTest() throws Exception { Object test = super.createTest(); manager.inject(test); return test; } }