Dependency Injection

Overview

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.

In the Java EE and CDI operation modes, Pax Exam uses the CDI BeanManager of the underlying Java EE server or CDI container to perform dependency injection.

In OSGi mode, 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.

In Web mode, Pax Exam uses either CDI or Spring to inject dependencies into test classes.

Dependency Injection in OSGi mode

Using the BundleContext API for acquiring services is rather low-level. Annotation-based injection is now a de facto standard in Enterprise Java. OSGi 4.2 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.

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

@RunWith(PaxExam.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.
  • 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.