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 using javax.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 type BundleContext 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.