Mock SharedServiceRegistry

Is there any way to inject a mock implementation of a SharedServiceRegistry for testing purposes? I am trying to test a class method that accesses the SharedServiceRegistry while running unit tests on a VDE.

I was able to mock out the storage service by the following, where MockStorageImpl is a mock class that implements the Storage interface:

Storage storage = new MockStorageImpl();
ServiceFactory.getServiceRegistry().register(Storage.class, storage);

But I can not find a way to provide a mock implementation of the SharedServiceRegistry.

It looks like it should be possible to define in a .properties file the name of the class that should implement this interface so that the DependencyInjectionServiceLoader can create it when it calls getImplementationName();

ej.wadapps.service.SharedServiceRegistry=NameOfMockImplementationClass

Alternatively, is it ok to register services that provide an implementation of a shared interface using:

ServiceFactory.getServiceRegistry().register() 

instead of:

SharedServiceFactory.getSharedServiceRegistry().register() ?

Is the separation of the two registrations important? ServiceFactory.getService() can find services registered using SharedServiceFactory.getSharedServiceRegistry().register() so it seems they are using the same registries internally?

First, here are some explanations of how the framework is working.
There are several way to declare services:

  • A service can be declared by dependency injection in a zzz.properties.list file in the kernel. Each line containing a definition:zz.Service=yy.Implementation. These services will be available all over the Java (kernel + applications)
  • It can be declared in META-INF/services in the applications. Each file named with the service fully qualified name and containing one line with the implementation fully qualified name. These services will only be accessible from the declaring application.
  • The service registry is used to propose services inside an application.
  • The shared service registry is used to propose services from an app to another app. So the registered service must be a shared interface.
    The service can be retrieved by ServiceFactory.getService(). In a multi-sandboxed context, the service will be searched as follows (in this order):
    1) in the services of the application (declared in META-INF/services),
    2) in the shared service registry (declared with SharedServiceFactory.getSharedServiceRegistry().register(),
    3) in the system properties (declared in a zzz.properties.list in the kernel),
    4) in the service registry of the application (declared with ServiceFactory.getServiceRegistry().register()).

To reply to But I can not find a way to provide a mock implementation of the SharedServiceRegistry.:
The implementation of SharedServiceRegistry can be declared in the kernel by a system property (zzz.properties.list file) with the key ej.wadapps.service.SharedServiceRegistry. It cannot be defined another way (in an application or in another registry).

@sebastien.eon

Thank you for the reply. I will give you some context.

I am trying to unit test my sandboxed applications so I do not want any dependencies on the kernel. I am unable to test the services’ start() methods as one of the responsibilities of the start() mthod is to register a shared interface in the SharedServiceRegistry. This registry is unavailable when performing a 'BuildModule so it throws an exception causing the test class to exit and fail the build.

Do you have any solution for this? Is there an ivy dependency I am can include with conf=“test” to bring in a mock SharedServiceRegistry? I don’t need it to do anything, just for calls to it not to fail.

Alga helped me sort it out via a conference call.

I had to add a ‘name.proprties.list’ file containing:

ej.wadapps.service.SharedServiceRegistry=ep.mocks.MockSharedServiceRegistryImpl

and a ‘name.types.list’ file containing:

ej.wadapps.service.SharedServiceRegistry
ep.mocks.MockSharedServiceRegistryImpl

Inside src/test/java and it worked perfectly to load my mock class.

To generate a code coverage report, it was necessary to add the following property to module.ivy:

<ea:property name="microej.testsuite.properties.s3.cc.activated" value="true"/>

And then use a MicroEJ Tool from the run config to decode it and generate an HTML report.