Hi,
I followed this AEM tutorial https://experienceleague.adobe.com/docs/experience-manager-learn/cloud-service/developing/advanced/s...
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 @reference. Please help
Solved! Go to Solution.
Views
Replies
Total Likes
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
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
Thanks,
Sherin
Hi @sherinregi , 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
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
They have explained a sequence of steps to follow. Also check the import packages for mock
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
Hi @sindhusr : You can refer this as well- https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/aem-servlet-junit-writing-...
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.
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies