Dependency Injection

Pax Exam supports the JSR-330 javax.inject.Inject annotation for injecting dependencies into test classes, even when these classes are not managed and instantiated by the dependency injection container of the system under test.

Pax Exam has its own method of type-safe dependency injection from the OSGi service registry using javax.inject.Inject and an optional @Filter annotation (since 2.3.0).

Pax Exam >= 2.3.0

Using the BundleContext API for acquiring services is rather low-level. Annotation-based injection is now a de facto standard in Enterprise Java. OSGi does not use annotations at all, to stay compatible with Java ME environments based on Java 1.4.

This restriction does not hold for Pax Exam, and annotation-based injection can significantly reduce the code size of tests.

Since 2.3.0, Pax Exam supports JSR-330 field injection for services and bundle contexts. Here is an example:

@RunWith(JUnit4TestRunner.class)
@ExamReactorStrategy(...)
public class SampleTest {

    @Inject
    private BundleContext bc;

    @Inject @Filter("(sophistication=major)")
    private CoolService coolService;


    @Configuration
    public Option[] config() {
       // ...
    }


    @Test
    public void test1() {
       assertEquals("It's so hot!", coolService.getResult());
    }
}

Points to note

  • Injection is indicated by a javax.inject.Inject annotation. Pax Exam's own Inject annotation of the 1.x release line is now deprecated.
  • Only field injection is supported. Constructor, setter or parameter injection will not work.
  • A field of type BundleContext annotated by @Inject will receive the bundle context of the current probe.
  • For other types, the Pax Exam injector tries to look up a service of the given type in the OSGi service registry. The lookup blocks while there is no matching service and fails the test if no service is found after a configurable timeout.
  • If there are multiple matching services, the first one gets injected.
  • The injected services are not proxied. Pax Exam does not currently offer a strategy for injected services going out of service...
  • An optional @Filter annotation can be added to restrict the set of eligible services. This annotation takes a String value, which is used as a filter in the usual OSGi LDAP filter syntax. Pax Exam automatically adds a service class clause to the filter (e.g. (objectClass=com.example.CoolService)).
  • The @Filter annotation has an optional timeout argument, specifying the lookup timeout in milliseconds.

Example

Have a look at the FilterTest in the Pax Exam Regression Test Suite.

Pax Exam 2.2.0

The only thing you can inject into your tests in Pax Exam 2.2.0 is a BundleContext. To do so, add a parameter of type BundleContext to your test methods. This does not require any additional annotations.

Pax Exam has no way to inject OSGi services. You need to acquire services via the BundleContext API.