JUnit Driver
Overview
The JUnit driver lets you write Pax Exam tests much like plain old JUnit tests, with a couple of modifications and restrictions. JUnit provides a very powerful extension mechanism through its @RunWith annotation, which is leveraged by Pax Exam.
This is the skeleton of a Pax Exam JUnit test:
@RunWith(PaxExam.class)
@ExamReactorStrategy(...)
public class SampleTest {
@Inject
private BundleContext bc;
@Inject @Filter("(sophistication=major)")
private CoolService coolService;
@Rule
public MethodRule rule = new MyMethodRule();
@Configuration
public Option[] config1() {
// ...
}
@Configuration
public Option[] config2() {
// ...
}
@Before
public void setUp() {
// ...
}
@After
public void tearDown() {
// ...
}
@Test
public void test1() {
// ...
}
@Test
public void test2() {
// ...
}
@Test
public void test3() {
// ...
}
}
In your @Configuration methods include this option:
org.ops4j.pax.exam.CoreOptions.junitBundles(),
Example
Have a look at the BeforeAfterTest in the Pax Exam Regression Test Suite.
Points to note
- The
@RunWith(PaxExam.class)annotation is required to hook Pax Exam into JUnit. - The
@ExamReactorStrategy(...)annotation lets you specify a reactor strategy. It is optional and defaults toPerMethodin OSGi mode orPerSuitein all other modes. - In OSGi mode, you need at least one no-args method with return type Option[] and annotated by
@Configuration. The method name does not matter. If there is more than one configuration method, each test method will be run for each of the given configurations. - In other modes, a
@Configurationis not required. You can use it to deploy additional modules. - Test methods are identified by the usual JUnit
@Testannotation. @Beforeand@Aftermethods work as expected. They are executed in the container before or after the test method.- Method rules with
@Ruleannotations also work as in vanilla JUnit. @BeforeClassand@AfterClassare not supported. (More precisely, methods with these annotations are run in the driver but not in the test container.) Class-level actions would require more significant changes in the internal design of Pax Exam, which is currently based on the assumption that one test corresponds to one method.- Pax Exam tests support Dependency Injection, using
@Injectannotations (and an optional@Filterin OSGi mode).
Compatibility Note
Pax Exam test annotations @Configuration, @ExamFactory, @ExamReactorStrategy now come from package org.ops4j.pax.exam so they can be shared with the TestNG driver. The old 2.x annotations from org.ops4j.pax.exam.junit are deprecated but still functional.
The JUnit runner is now called PaxExam. The old name JUnit4TestRunner is still working but deprecated.
Parameterized Tests
Since 3.2.0.
In addition to PaxExam, the JUnit driver contains a PaxExamParameterized runner for executing parameterized tests.
This runner reuses the @Parameters and @Parameter annotations from JUnit. To turn a vanilla parameterized test into a Pax Exam test with an embedded container and service injection, simply replace Parameterized by PaxExamParameterized:
import org.ops4j.pax.exam.junit.PaxExamParameterized;
@RunWith(PaxExamParameterized.class)
public class CalculatorTest {
@Inject
private Calculator calculator;
private int a;
private int b;
private int sum;
@Parameters
public static List<Object[]> getParameters() {
return Arrays.asList(new Object[][] {
{2, 3, 5},
{6, 2, 8}
});
}
public CalculatorTest(int a, int b, int sum) {
this.a = a;
this.b = b;
this.sum = sum;
}
@Test
public void add() {
assertThat(calculator.add(a, b), is(sum));
}
}