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.
Pax Exam >= 2.4.0
To successfully use the 2.4.0 JUnit driver you need to do at least these steps:
Include the pax bundle:
<dependency> <groupId>org.ops4j.pax.exam</groupId> <artifactId>pax-exam-junit4</artifactId> <version>2.4.0</version> <scope>test</scope> </dependency>
Use the same version of junit that pax exam expects:
<dependency> <groupId>org.apache.servicemix.bundles</groupId> <artifactId>org.apache.servicemix.bundles.junit</artifactId> <version>4.9_2</version> <scope>test</scope> </dependency>
Supply a source for javax.inject.Inject such as
<dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-atinject_1.0_spec</artifactId> <version>1.0</version> <scope>test</scope> </dependency>
In your test class @Configuration method include this option:
org.ops4j.pax.exam.CoreOptions.junitBundles(),
Pax Exam 2.3.0
This release introduces @Before and @After annotation support and JSR-330 field injection for services and bundle contexts.
Here is an example of what you can do with the current Pax Exam release:
@RunWith(JUnit4TestRunner.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() {
// ...
}
@Before
public void tearDown() {
// ...
}
@Test
public void test1() {
// ...
}
@Test
public void test2() {
// ...
}
@Test
public void test3() {
// ...
}
}
Additions, Changes and Restrictions
- Pax 2.3.0 supports JUnit 4.9.
@Beforeand@Aftermethods now 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 still not supported. This would require more significant changes in the internal design, which is currently based on the assumption that one test corresponds to one method.- To be closer to JUnit standards, test methods are no longer allowed to have parameters. Use field injection to obtain a
BundleContext. (This is what we had back in Pax Exam 1.x, but now we're usingjavax.inject.Injectinstead of our own annotation.) Thus, Pax Exam 2.3.0 is not backward compatible to earlier 2.x releases. - The improved JUnit support depends on Dependency Injection which lets you inject your services, using
@Injectand optional@Filterannotations.
Example
Have a look at the BeforeAfterTest in the Pax Exam Regression Test Suite.
Pax Exam 2.2.0
This is the skeleton of a Pax Exam JUnit test for the previous release:
@RunWith(JUnit4TestRunner.class)
@ExamReactorStrategy(...)
public class SampleTest {
@Configuration
public Option[] config1() {
// ...
}
@Configuration
public Option[] config2() {
// ...
}
@Test
public void test1(BundleContext bc) {
// ...
}
@Test
public void test2(BundleContext bc) {
// ...
}
@Test
public void test3(BundleContext bc) {
// ...
}
}
Points to note
- Pax Exam 2.2.0 supports JUnit 4.4.0.
- The
@RunWith(JUnit4TestRunner.class)annotation is required to hook Pax Exam into JUnit. - The
@ExamReactorStrategy(...)annotation lets you specify a reactor strategy. It is optional and defaults to@ExamReactorStrategy(AllConfinedStagedReactorFactory.class) - 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. - Test methods are identified by the usual JUnit
@Testannotation. Differing from JUnit, Pax Exam allows or even recommends you to add a single argument of typeBundleContextto your test methods. Using this bundle context, you can interact with the framework under test. - Setup and teardown methods annotated by
@Before, @After, @BeforeClass, @AfterClassare not supported. More precisely, they are executed in the driver context and not in the container context, which is not really what you'd expect, so it is recommended to work with plain old@Testmethods only. - Service injection is not supported. You need to work with the
BundleContextAPI to lookup service references and services.