/*
* 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;
}
}