Showing posts with label UnitTesting. Show all posts
Showing posts with label UnitTesting. Show all posts

May 30, 2013

Tinybundles, a little gem for OSGi testing

In my OSGi applications I often make use of the OSGi extender pattern. An excellent example is available on Kai's Toedter blog.

As Peter Kriens explained:
In the Synchronous Bundle Listener event call back, the subsystem can look at the resources of the bundle and check if there is anything of its liking. If it is, it can use this resource to perform the necessary initialization for the new bundles.

Writing unit tests for a Synchronous Bundle Listener is often a tricky task. To test the behaviour of your extender you need to install and start (and later stop and uninstall) bundles via the OSGi API.

The API allows you to install a bundle by passing in an InputStream opened from a bundle file. So, the simplest solution usually consists in packaging a small test bundle as a binary resource in the test case  package, and to use the OSGi API from the test case class to install the bundle in the OSGi framework. This approach certainly works but is quite annoying because you need to repackage the test bundle every time you have to make a change.

Some time ago I found a better solution: the Tinybundles library. The project documentation is here, while sources for the library are available on github.

Tinybundles provides a convenient API to create an OSGi bundle from resources and classes available in your test case classpath:

TinyBundle bundle = TinyBundles.bundle()
            .add( TestActivator.class )
            .add( HelloWorld.class )
            .set( Constants.BUNDLE_SYMBOLICNAME, "test.bundle" )
            .set( Constants.EXPORT_PACKAGE, 
                HelloWorld.class.getPackage().getName() )
            .set( Constants.IMPORT_PACKAGE, 
                "org.apache.commons.collections" )
            .set( Constants.BUNDLE_ACTIVATOR, 
                TestActivator.class.getName() );

InputStream is = bundle.build(TinyBundles.withBnd());        
Bundle installed = getBundleContext().installBundle("dummyLocation", is);
installed.start();

In this way you can generate bundles on-the-fly within your test case for the purpose of testing your bundle listeners.

Simple, isn't it?