Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Unable to inject OSGI Services: jUnit Test Case !!

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
Community Advisor

It's been a while, but if you want to mockInject an OSGI service into your underTest object, then you must use MockitoExtension, so you can @injectMocks. And the WCM IO testing library to register the OSGI service into the calling container, https://wcm.io/testing/.

Here's some example code:

import io.wcm.testing.mock.aem.junit5.AemContext;
import org.apache.sling.api.resource.Resource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@ExtendWith({ AemContextExtension.class, MockitoExtension.class })
class MySlingModelTest {

    private final AemContext aemContext = AppAemContext.newAemContext();

    @Mock
    Resource resource;

    @Mock
    MyConfigurationService myConfigurationService;

    @InjectMocks
    MySlingModel slingModel;

    @test
    void testSlingModel() {
        // Register the configuration service in the AemContext
        aemContext.registerService(MyConfigurationService.class, myConfigurationService);

        // Mock the behavior of the resource and myConfigurationService
        when(resource.getPath()).thenReturn("/content/mypage");
        when(myConfigurationService.getConfiguration()).thenReturn("Test Configuration");

        // Adapt the sling model using the AemContext
        slingModel = aemContext.adaptTo(MySlingModel.class);

        // Call a method on the sling model
        String result = slingModel.getTitle();

        // Assert the expected result
        assertEquals("My Title", result);
    }
}

View solution in original post

1 Reply

Avatar

Correct answer by
Community Advisor

It's been a while, but if you want to mockInject an OSGI service into your underTest object, then you must use MockitoExtension, so you can @injectMocks. And the WCM IO testing library to register the OSGI service into the calling container, https://wcm.io/testing/.

Here's some example code:

import io.wcm.testing.mock.aem.junit5.AemContext;
import org.apache.sling.api.resource.Resource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@ExtendWith({ AemContextExtension.class, MockitoExtension.class })
class MySlingModelTest {

    private final AemContext aemContext = AppAemContext.newAemContext();

    @Mock
    Resource resource;

    @Mock
    MyConfigurationService myConfigurationService;

    @InjectMocks
    MySlingModel slingModel;

    @test
    void testSlingModel() {
        // Register the configuration service in the AemContext
        aemContext.registerService(MyConfigurationService.class, myConfigurationService);

        // Mock the behavior of the resource and myConfigurationService
        when(resource.getPath()).thenReturn("/content/mypage");
        when(myConfigurationService.getConfiguration()).thenReturn("Test Configuration");

        // Adapt the sling model using the AemContext
        slingModel = aemContext.adaptTo(MySlingModel.class);

        // Call a method on the sling model
        String result = slingModel.getTitle();

        // Assert the expected result
        assertEquals("My Title", result);
    }
}