Introduction
The Amdatu Testing project provides static utilities to simplify OSGi service integration tests. It currently supports the following features:
-
Inject service references automatically to your test class
-
Configure services and service factories using ConfigurationAdmin
-
Register services as part of the test setup
Additonal testing support is provided by other Amdatu projects. Projects providing additional testing support:
-
Amdatu Mongodb
-
Amdatu Web
For more information about test support provides by thees project see the documentation of these projects.
How to use
Service injection
Test configuration should be done in your test’s setup method by invoking TestConfigurator.configure(this) followed by adding components and configuration. The apply() method should be called after all steps have been specified, to actually apply the configuration to the test case and create the test context. The API to create dependencies stays very close to the Dependency Manager API. The test context should be cleaned up on tear down by calling TestConfigurator.cleanUp(this).
The example below demonstrates how to inject the Example service in our test case. The full example can be found on BitBucket.
package org.amdatu.testing.example.test;
import static org.junit.Assert.assertEquals;
import org.amdatu.testing.configurator.TestConfigurator;
import org.amdatu.testing.example.Example;
import org.junit.Before;
import org.junit.Test;
import org.junit.After;
public class ExampleTest {
private volatile Example serviceToTest;
@Before
public void setup() {
TestConfigurator.configure(this)
.add(TestConfigurator.createServiceDependency()
.setService(Example.class)
.setRequired(true))
.apply();
}
@After
public void after() {
TestConfigurator.cleanUp(this);
}
@Test
public void test() {
String hello = serviceToTest.hello();
assertEquals("Hello from org.amdatu.testing.example", hello);
}
}
Running tests
Integration tests live in their own project, because they will run as a real bundle in an OSGi framework while executing the tests.
The bnd.bnd file should contain a run configuration that consists of all the bundles required to run the bundles that are being tested, plus junit, and additional testing libraries (such as Amdatu Testing).
To run tests you use the standard Bnd integration testing support, for this we need to add a Test-Cases
header.
This header is by Bnd to determine which tests it should run.
-buildpath: \
org.amdatu.testing.configurator;version=latest,\
org.amdatu.testing.example;version=latest,\
org.apache.servicemix.bundles.junit
-runbundles: \
org.apache.servicemix.bundles.junit,\
org.mockito.mockito-core,\
org.objenesis,\
net.bytebuddy.byte-buddy,\
net.bytebuddy.byte-buddy-agent,\
org.amdatu.testing.configurator;version=latest,\
org.amdatu.testing.example;version=latest
-runfeatures: base
-runfw: org.apache.felix.framework
Test-Cases: \
org.amdatu.testing.example.test.ExampleTest
Private-Package: \
org.amdatu.testing.example.test
Amdatu Blueprint provides features and project templates that make it easier to setup a new test. |
Specifying a service filter
It is sometimes required to specify a service dependency with a filter. This can be done easily by passing an additional parameter to the createServiceDependency() method as follows:
@Before
public void setup() {
TestConfigurator.configure(this)
.add(TestConfigurator.createServiceDependency()
.setService(Example.class, "(someKey=someValue)")
.setRequired(true))
.apply();
}
Configuring components
Some components rely on Configuration Admin to be configured. This can be easily done using the TestConfigurator using the createConfiguration method.
package org.amdatu.testing.example.test;
import static org.junit.Assert.assertEquals;
import org.amdatu.testing.configurator.TestConfigurator;
import org.amdatu.testing.example.Example;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ExampleConfigurationTest {
private volatile Example serviceToTest;
@Before
public void setup() throws InterruptedException {
TestConfigurator.configure(this)
.add(TestConfigurator.createServiceDependency()
.setService(Example.class)
.setRequired(true))
.add(TestConfigurator.createConfiguration("org.amdatu.testing.example")
.set("message", "Hi")
.setSynchronousDelivery(true))
.apply();
}
@After
public void after() {
TestConfigurator.cleanUp(this);
}
@Test
public void test() {
String hello = serviceToTest.hello();
assertEquals("Hi from org.amdatu.testing.example", hello);
}
}
Because Configuration Admin works asynchronously, you have to be sure that the component is configured before you start your test. Especially with optional configurations this can be a problem. The TestConfigurator supports synchronous delivery of the configuration to work around this problem using the ServiceConfigurator.setSynchronousDelivery method. When using this the ConfigurationAdmin service is bypassed and the configuration is applied to the ManagedService directly. |
Registering services
It is sometimes required to define a new OSGi component as part of the test setup, for example for mocking some services. Here is an example demonstrating how to create a new component and specify its dependencies:
@Before
public void setup() {
TestConfigurator.configure(this)
.add(TestConfigurator.createComponent()
.setInterface(MyService.class)
.setImplementation(myServiceMock))
.apply();
}
Providing groups of reusable configuration steps
It’s not uncommon to have multiple tests in your project performing rather similar configurations on setup. For example defining database configurations. Amdatu-testing lets you conveniently wrap a bunch of configuration steps and reuse them throughout your project. Below is an example demonstrating how to create such a reusable configuration.
class TestUtils {
public static ConfigurationSteps reusableConfig() {
return ConfigurationSteps.create()
.add(createServiceDependency()
.setService(Example.class)
.setRequired(true));
}
}
These reusable configuration steps can now be used like demonstrated below.
@Before
public void setup() {
TestConfigurator.configure(this)
.add(TestUtils.reusableConfig())
.apply();
}
Components
Amdatu Testing provides the following static testing utility components:
Bundle |
Required |
Description |
org.amdatu.testing.configurator |
yes |
Used to configure and inject services in test setup |
Dependencies
The following table is an overview of the required and optional dependencies for Amdatu Testing:
Bundle |
Required |
Description |
org.apache.felix.dependencymanager |
yes |
Apache Felix Dependency Manager is used internally by all Amdatu components |
OSGi ConfigurationAdmin service (e.g. Apache Felix ConfigAdmin) |
yes |
Used to configure the services which are going to be tested |
OSGi LogService (e.g. Apache Felix LogService) |
no |
Used to log output |
Resources
Tools |
Location |
Source Code |
|
Issue Tracking |
|
Continuous Build |
https://bitbucket.org/amdatu/amdatu-testing/addon/pipelines/home |