Unable to inject mandatory reference in aem unit testing. | Community
Skip to main content
Level 2
January 9, 2024
Solved

Unable to inject mandatory reference in aem unit testing.

  • January 9, 2024
  • 3 replies
  • 2348 views

Hi,

I followed this AEM tutorial https://experienceleague.adobe.com/docs/experience-manager-learn/cloud-service/developing/advanced/service-users.html?lang=en

to set up a service class that loads once service user object is available. 

 

 

 

 

@Component( reference = { @Reference( name = wknd-examples-statistics, service = ServiceUserMapped.class, target = "(subServiceName=wknd-examples-statistics)" ) } ) public class ContentStatisticsImpl implements ContentStatistics {

 

 

 

 

My service works fine. The issue is when I am unit testing.

I get this error while unit testing:

org.apache.sling.testing.mock.osgi.ReferenceViolationException: Unable to inject mandatory reference 'wknd-examples-statistics' (org.apache.sling.serviceusermapping.ServiceUserMapped) for class com.adobe.aem.wknd.examples.core.statistics.impl.ContentStatisticsImpl

: no matching services were found. bundleContext=org.apache.sling.testing.mock.osgi.MockBundleContext@298f7b0a.

 

Error occurs when I inject the service as below:

context.registerInjectActivateService(newContentStatisticsImpl());

How do i mock @3214626. Please help

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by sindhusr

Hi @sindhusr 

You can ignore the clreplaced one. The steps you followed looks rite to me . The error now you are getting looks a different one and i feel it could be related to the details given in the below links. Could you please check on that 

https://groups.google.com/g/wcm-io-dev/c/JzFnXsY6XZk?pli=1

 

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/runtime-error-while-running-junit5-aem-mocks-test/td-p/423259

 

They have explained a sequence of steps to follow. Also check the import packages for mock 

ref: https://programtalk.com/vs4/java/adobe/commerce-cif-connector/bundles/cif-virtual-catalog/src/test/java/com/adobe/cq/commerce/virtual/catalog/data/impl/ProductBindingCreatorTest.java/

 

 

 


Hi, I resolved it by adding a bind method:

@Component( reference = { @Reference( name = wknd-examples-statistics, service = ServiceUserMapped.class, target = "(subServiceName=wknd-examples-statistics)", bind = "setServiceUserMapped" ) } ) public class ContentStatisticsImpl implements ContentStatistics { @Reference private ServiceUserMapped serviceUserMapped; public void setServiceUserMapped(ServiceUserMapped serviceUserMapped) { this.serviceUserMapped = serviceUserMapped; } //other code } Test case: public class ContentStatisticsImplTest { @BeforeEach public void setup() { serviceUserMapped = mock(ServiceUserMapped.class); context.registerService(ServiceUserMapped.class,serviceUserMapped, ImmutableMap.of(ServiceUserMapped.SUBSERVICENAME,"wknd-examples-statistics")); }

Thanks for your help. @sherinregi-1 

3 replies

sherinregi-1
Community Advisor
Community Advisor
January 9, 2024

Hi @sindhusr 

One thing i notice here is you are trying yo use registerInjectActivateService on the same class you are on. In your case you are referencing a markerservice serviceusermapped and that reference needs to be mocked inorder to prevent this exception .

 

Can you try to do inject that and use the same in setup and then invoke

 

Try something similar 

 

https://programtalk.com/java-more-examples/io.wcm.testing.mock.aem.junit.AemContext.registerService()/

Ref: https://developer.adobe.com/experience-manager/reference-materials/6-5/javadoc/org/apache/sling/serviceusermapping/ServiceUserMapped.html

 

Thanks,

Sherin

 

sindhusrAuthor
Level 2
January 9, 2024

Hi @sherinregi-1 , Thank you for your response.

What is ServiceUserMapped.clreplaced? I cannot resolve that on my IDE nor can I find references to it.

This is what I tried:

ServiceUserMapped serviceUserMapped = Mockito.mock(ServiceUserMapped.class);
context.registerService(ServiceUserMapped.class,serviceUserMapped,ImmutableMap.of(ServiceUserMapped.SUBSERVICENAME,"wknd-examples-statistics"));
context.registerInjectActivateService(newContentStatisticsImpl());

 Now I get the below error:

java.lang.RuntimeException: No bind/unbind method name or file name defined for reference wknd-examples-statistics

 

sherinregi-1
Community Advisor
Community Advisor
January 10, 2024

Hi @sindhusr 

You can ignore the clreplaced one. The steps you followed looks rite to me . The error now you are getting looks a different one and i feel it could be related to the details given in the below links. Could you please check on that 

https://groups.google.com/g/wcm-io-dev/c/JzFnXsY6XZk?pli=1

 

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/runtime-error-while-running-junit5-aem-mocks-test/td-p/423259

 

They have explained a sequence of steps to follow. Also check the import packages for mock 

ref: https://programtalk.com/vs4/java/adobe/commerce-cif-connector/bundles/cif-virtual-catalog/src/test/java/com/adobe/cq/commerce/virtual/catalog/data/impl/ProductBindingCreatorTest.java/

 

 

 

Kamal_Kishor
Community Advisor
Community Advisor
January 9, 2024
Raja_Reddy
Community Advisor
Community Advisor
January 9, 2024

Hi @sindhusr 
when unit testing OSGi components that have@Reference annotations, you need to simulate the OSGi environment and register the services your component depends on. The error you're encountering indicates that the required service (wknd-examples-statistics) is not being provided in the test environment.
You can use the @Designate annotation along with @OsgiService to mock and register the required service during unit testing. Here's an example:

import org.apache.sling.serviceusermapping.ServiceUserMapped; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @Component( immediate = true, service = ContentStatistics.class ) @Designate(ocd = ContentStatisticsImpl.Config.class) public class ContentStatisticsImpl implements ContentStatistics { @Reference private ServiceUserMapped wkndExamplesStatisticsService; // Other code... @Activate @Modified protected void activate(Config config) { // Your activation logic } // Configuration interface @ObjectClassDefinition(name = "Content Statistics Configuration") public @interface Config { @AttributeDefinition(name = "Sub Service Name", description = "The sub-service name") String subServiceName() default "wknd-examples-statistics"; } }

 

you can then use @OsgiServiceto mock and register the required service:

 

 

import org.apache.sling.serviceusermapping.ServiceUserMapped; import org.junit.jupiter.api.Test; import org.apache.sling.testing.mock.osgi.MockOsgi; class ContentStatisticsImplTest { @Test void testContentStatistics() { // Mock the ServiceUserMapped service ServiceUserMapped wkndExamplesStatisticsService = MockOsgi .newService(ServiceUserMapped.class) .property("subServiceName", "wknd-examples-statistics") .build(); // Register the mocked service MockOsgi.injectServices(new ContentStatisticsImpl(), wkndExamplesStatisticsService); // Your test logic here } }

This approach allows you to simulate the OSGi environment and register the required services for your unit tests.

Thanks.