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.
@Before
and@After
methods now work as expected. They are executed in the container before or after the test method.- Method rules with
@Rule
annotations also work as in vanilla JUnit. @BeforeClass
and@AfterClass
are 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.Inject
instead 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
@Inject
and optional@Filter
annotations.
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
@Test
annotation. Differing from JUnit, Pax Exam allows or even recommends you to add a single argument of typeBundleContext
to your test methods. Using this bundle context, you can interact with the framework under test. - Setup and teardown methods annotated by
@Before, @After, @BeforeClass, @AfterClass
are 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@Test
methods only. - Service injection is not supported. You need to work with the
BundleContext
API to lookup service references and services.