Child pages
  • Getting Started with OSGi Tests
Skip to end of metadata
Go to start of metadata

A simple Pax Exam JUnit test

While JUnit is not the only way of using Pax Exam, it is probably the one that most users prefer, so let us look at a simple piece of source code.

After explaining the meaning of the Pax Exam annotations and APIs you see in this snippet, we'll discuss how to set up your environment for creating and running your own Pax Exam tests.

package com.example.myproject.test;

import static org.junit.Assert.*;
import static org.ops4j.pax.exam.CoreOptions.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.Configuration;
import org.ops4j.pax.exam.junit.ExamReactorStrategy;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
import org.ops4j.pax.exam.spi.reactors.AllConfinedStagedReactorFactory;
import org.ops4j.pax.exam.util.ServiceLookup;
import org.osgi.framework.BundleContext;
import javax.inject.Inject;
import com.example.myproject.HelloService;

public class SampleTest {

    private HelloService helloService;

    public Option[] config() {

        return options(
            mavenBundle("com.example.myproject", "myproject-api", "1.0.0-SNAPSHOT"),

    public void getHelloService() {
        assertEquals("Hello Pax!", helloService.getMessage());

The @RunWith(JUnit4TestRunner.class) annotation is enough to hook Pax Exam into JUnit and let it do its magic of setting up a test container with an OSGi framework and your bundles under test.

The @ExamReactorStrategy annotation determines whether or not the OSGi framework gets restarted for every single test. The value used here is actually the default (so you could drop this annotation), indicating that the framework will be restarted for each test to provide a maximum of isolation.

Configuring the Test Container

Any Pax Exam JUnit test requires a method annotated with @Configuration returning an array of configuration options. These options define the set of bundles to be provisioned to the OSGi framework in the test container. You create options by calling static methods coming from

import static org.ops4j.pax.exam.CoreOptions.*;

Pax Exam has a large number of configuration options, but for standard use cases, you only need to remember the five or six most important ones.

mavenBundle() lets you specify a bundle in terms of its Maven coordinates. It will be provisioned to the test container from a local or remote Maven repository using the standard Maven lookup and caching procedures.

Using bundle(), you can provision a bundle from any kind of URL supported by Pax URL. Of course, this includes the standard file: and http: protocols, and there are some specialized protocols for grouping bundles, scanning directories and other useful things.

junitBundles() provisions JUnit and its dependencies as OSGi bundles to the test container.

Test Methods

Any method annotated with @Test will be run as a test within the OSGi framework launched by the test container.

Pax Exam builds a bundle on the fly called test probe which contains your test class and installs this bundle in the test container.

Using Dependency Injection on fields marked with @javax.inject.Inject, the body of your test method can access the BundleContext of the probe bundle or any service obtained from the OSGi service registry.

The test probe contains a DynamicImport-Package: * manifest header, so your test methods work with any package exported by any bundle in your test container.

@Before or @After methods and @Rule fields are supported since Pax Exam 2.3.0.

Next Steps

The test container and the OSGi framework used for running your tests are looked up from the classpath using java.util.ServiceLoader.

Read more about setting up the Maven dependencies for running Pax Exam tests.

  • No labels