Unit Test for Sling Model Delegation Pattern
content / aem-demo / components / button.json
{
"button": {
"jcr:primaryType": "nt:unstructured",
"jcr:title": "Discussion Guide",
"textColor": "text-primary",
"backgroundColor": "bg-primary",
"icon": "adobe",
"sling:resourceType": "aem-demo/components/button"
}
}
sling:resourceSuperType
delegation chain. Without proper component definitions, the @Via(type = ResourceSuperType.class)
injection will fail, causing test failures.apps / aem-demo / components / button.json
{
"button": {
"jcr:primaryType": "cq:Component",
"sling:resourceSuperType": "core/wcm/components/button/v2/button",
"componentGroup": "AEM Demo - Content",
"jcr:title": "Button",
"sling:resourceType": "aem-demo/components/button"
}
}
apps / core /components / button.json
{
"button": {
"jcr:primaryType": "cq:Component",
"componentGroup": "Core WCM Components",
"jcr:title": "Button",
"sling:resourceType": "core/wcm/components/button/v2/button"
}
}
ButtonImpl.java
public class ButtonImpl implements Button {
protected static final String RESOURCE_TYPE = "aem-demo/components/button";
private com.adobe.cq.wcm.core.components.models.Button coreButton;
public String getText() {
// ... custom implementation ...
return button.getText();
}
public String getExportedType() {
return ButtonImpl.RESOURCE_TYPE;
}
private interface DelegationExclusion {
String getText();
String getExportedType();
}
}
AemContext
. The test setup includes loading component definitions, test content, and properly registering the Sling Models for testing.ButtonImplTest.java
public class ButtonImplTest {
private final AemContext context = new AemContextBuilder(ResourceResolverType.JCR_MOCK)
.plugin(ContextPlugins.CORE_COMPONENTS)
.build();
public void setUp() {
// Load component definitions from JSON
context.load().json("/apps/aem-demo/components/button.json", "/apps/aem-demo/components");
context.load().json("/apps/core/components/button.json", "/apps/core/wcm/components/button/v2");
// Load test content
context.load().json("/content/aem-demo/components/button.json", "/content");
context.currentResource("/content/button");
// Register all necessary models
context.addModelsForClasses(ButtonImpl.class);
}
public void testButton() {
ModelFactory modelFactory = context.getService(ModelFactory.class);
Button button = Objects.requireNonNull(modelFactory)
.createModel(context.request(), ButtonImpl.class);
Assertions.assertNotNull(button);
Assertions.assertEquals(ButtonImpl.RESOURCE_TYPE, button.getExportedType());
Assertions.assertEquals("text-primary", button.getTextColor());
Assertions.assertEquals("bg-primary", button.getBackgroundColor());
Assertions.assertEquals("Discussion Guide", button.getText());
}
}