Expand my Community achievements bar.

SOLVED

Unable to Inject OSGI Services: jUnit !!

Avatar

Level 1

I am unable to get the reference of the OSGI Services when ran through Mockito. Every time I run the Test Class it gives me null wherever that service is invoked.

Any help is highly appreciated.

I am following this tutorial: Apache Sling - OSGi Mocks , but no luck.

Below is the code snippet (Test Class) that i run:

HashMap<Object, Object> _configServiceEndpoint = new HashMap<Object, Object>();

  HashMap<Object, Object> _configCommonConfig = new HashMap<Object, Object>();

  /** Mocking required sling request params */

  slingRequest = mock(SlingHttpServletRequest.class);

  /** Mocking required sling request params */

  slingResponse = mock(SlingHttpServletResponse.class);

  /** Setting Service End Point */

  _configServiceEndpoint.put("sendEmailURL",

  "https://MLIGATEWAY.MAXLIFEINSURANCE.COM/mli/prod/soa/MLI_E-mail_rest");

  _configServiceEndpoint.put("sendSmsURL", "https://gatewayuat.maxlifeinsurance.com/apimgm/sb/soa/sms/v2/real");

  _configServiceEndpoint.put("otpGenerationURL",

  "https://gatewayuat.maxlifeinsurance.com/apimgm/sb/soa/otp/generate?client_id=763b645e-4034-4152-9631...");

  _configServiceEndpoint.put("otpValidationURL",

  "https://gatewayuat.maxlifeinsurance.com/apimgm/sb/soa/otp/validate?client_id=763b645e-4034-4152-9631...");

  serviceEndPointConfigImpl = context.registerInjectActivateService(new ServiceEndPointImpl(),

  _configServiceEndpoint);

  /** Mocking up the timeout config needed for service Agent class */

  _configCommonConfig.put("serviceTimeOut", "25000");

  //commonConfigImpl = context.registerInjectActivateService(new CommonConfigImpl(), _configCommonConfig);

  GenerateOTP generateOTP = new GenerateOTP();

  SendOtpSms sendOtpSms = new SendOtpSms();

  SendOtpEmail sendOtpEmail = new SendOtpEmail();

  //ServiceAgent serviceAgent = new ServiceAgent();

  CommonConfigImpl commonConfig = new CommonConfigImpl();

  commonConfig = mock(CommonConfigImpl.class);

  serviceAgent = mock(ServiceAgent.class);

  BundleContext bundleContext = MockOsgi.newBundleContext();

  MockOsgi.activate(commonConfig, bundleContext, _configCommonConfig);

  //MockOsgi.injectServices(cmConfig, bundleContext);

  MockOsgi.activate(serviceAgent, bundleContext);

  MockOsgi.injectServices(commonConfig, bundleContext);

  MockOsgi.activate(generateOTP, bundleContext);

  MockOsgi.injectServices(serviceAgent, bundleContext);

  MockOsgi.activate(sendOtpSms, bundleContext);

  MockOsgi.injectServices(serviceAgent, bundleContext);

  MockOsgi.activate(sendOtpEmail, bundleContext);

  MockOsgi.injectServices(serviceAgent, bundleContext);

    

@Test

    public void testMethods() throws Exception{

  this.doGet(slingRequest, slingResponse);

    }

The class where "doGet" is implemented, has two service References which internally reference another Service.

It gives me the following error:

org.apache.sling.testing.mock.osgi.ReferenceViolationException: Unable to inject mandatory reference 'commonConfig' for class com.mli.neo.global.http.ServiceAgent : no matching services were found.

  at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.injectServiceReference(OsgiServiceUtil.java:407)

  at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.injectServices(OsgiServiceUtil.java:390)

  at org.apache.sling.testing.mock.osgi.MockOsgi.injectServices(MockOsgi.java:148)

  at com.mli.neo.global.SendOTPTest.<init>(SendOTPTest.java:90)

  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

  at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

  at java.lang.reflect.Constructor.newInstance(Unknown Source)

  at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:178)

  at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:227)

  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)

  at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:224)

  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)

  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)

  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)

  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)

  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)

  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)

  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)

  at org.junit.runners.ParentRunner.run(ParentRunner.java:292)

  at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)

  at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)

  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)

  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)

  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)

  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)

  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Request a concrete solution to achieve this. Any help is highly appreciated.

Regards,Deepak Kumar

1 Accepted Solution

Avatar

Correct answer by
Level 4

normally this error happens because you have missed mocking some internal operation as well, for example, if your method internally has something like this session.getRootNode().addNode(...); in this case, your test must also mock  getRootNode().addNode(...) otherwise your method will fail

View solution in original post

6 Replies

Avatar

Level 10

Watch this GEMS session on testing - it will point you in the right direction: From Unit Testing to Integration Test of an AEM Application

Avatar

Correct answer by
Level 4

normally this error happens because you have missed mocking some internal operation as well, for example, if your method internally has something like this session.getRootNode().addNode(...); in this case, your test must also mock  getRootNode().addNode(...) otherwise your method will fail

Avatar

Level 2

Could you share the Code snippet of your class?

Avatar

Level 1

Thanks, Diego
I tried Power Mock and it worked.

Avatar

Level 1

I got the same error and easily fixed to add all the dependency services (i.e. @reference ) to context via context.registerService method. For example your service has a reference to QueryBuilder like @ @Referenceprivate QueryBuilder builder; then you need to do 2 things in your test class. first, create a mock @Mock QueryBuilder builder; 2nd - context.registerService(QueryBuilder.class, builder); in your setup method the definitely problem will be solved.