Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit-Testing OSGi-Components

I'm currently thinking of "How to design an OSGi component so that it's easy to write tests for it with frameworks like jUnit and Mockito".

Mocking inter-bundle-dependencies is quite easy since OSGi strengthens the DIP (Dependency Inversion Principle) and injector-methods (e.g. setter) usually exist.
But what about bundle internal dependencies?

For example look at this case. Now I want to bring it into an OSGi context... Image we want to provide any kind of network protocol as a declarative service in an OSGi platform and want to write unit-tests for testing the lower networking code which is directly interacting with the socket object.

If we would refactor the socket creation into a separate but still bundle internal POJO (Plain Old Java Object) class, how should we inject it into the protocol implementation?

  • In the unit test we could simply use a setter method but who would do this in the OSGi container for us?
  • Subclassing the tested class and overwriting a creator-method would only work if the tested class is not declared as final.
like image 583
Marc-Christian Schulze Avatar asked Aug 09 '11 23:08

Marc-Christian Schulze


1 Answers

Testing the interaction with the OSGi container is, strictly speaking, an integration test. For this you could use Pax Exam, it's a bit fiddly to get the hang of, but works really well (especially if you're using maven and/or karaf features).

Additionally you can use TinyBundles which can dynamically create deployable bundles/fragments from within your test (very cool) to mock out other bundles/fragments to ensure inter-bundle integration without bring up a full environment.

For unit or small scale integration testing (i.e. without the container) then you can just mock out the BundleContext (or if using DS the ComponentContext as well) should you need it.

I'm a little unclear about your questions in the bullet points. If there's an internal POJO then it'd be your responsibility to wire up dependencies via setters, otherwise if it exposed to the OSGi service registry then dependencies are resolved by the framework (either DS or ServiceTracker).

Also subclassing something to overwrite a creator-method means you're no longer testing the original class - this is a code smell - try refactoring it to pass in the creator code as a separate class (constructor or setter), then this new creator code (socket creation) can be tested independently (with no consideration for OSGi or even the protocol class where it will be used).

like image 192
earcam Avatar answered Oct 01 '22 05:10

earcam