Expand my Community achievements bar.

it's still a problem, How to Unit test case for Sling delegation pattern?

Avatar

Level 2

It's still a problem. I am using the latest AEM Maven Archetype to customize the Teaser component, but unable to pass my tests because of the delegation pattern. I scaveraged through the net and have already reviewed all the possible answers like:

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/unit-test-case-for-sling-d...

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/junit-test-cases-for-sling...

 

@arunpatidar and other folks, can you please help me out by giving me a working version of a Delegation pattern?

 

Here's a very simple sling model component that needs JUNIT5. I am also on the latest AEM 6.5 version + Latest AEM Maven Archetype version

 

@Model(adaptables = SlingHttpServletRequest.class, resourceType = CustomTeaser.RESOURCE_TYPE, 
        defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class CustomTeaser implements com.adobe.cq.wcm.core.components.models.Teaser {
    public static final String RESOURCE_TYPE = "mycomp/components/customteaser";

    @Self
    @Via(type = ResourceSuperType.class)
    private com.adobe.cq.wcm.core.components.models.Teaser teaser;
    
    @Override
    public String getTitle() {
        return teaser.getTitle();
    }
}

 

Whenever I am using AEMContext or Mocks, while in debug mode, teaser is ALWAYS NULL.

9 Replies

Avatar

Level 2

Hello, what is the CustomTeaserTest.json can you please share it?

Avatar

Community Advisor

Hello @2490242973 ,

Please follow my article. I gave two examples for considering different cases. (Breadcrumb & Language Navigation).

Hope this will help you and your problem will be solved.

https://sadyrifat.medium.com/aem-unit-test-case-for-sling-delegation-pattern-1f011b947fb3 

The main problem of the delegation pattern you just mention is null. This is solved.

Avatar

Level 2

Hi @Sady_Rifat,

Thanks for the details documentation. I am trying to extend the title component here and still getting Error :

Caused by: org.apache.sling.testing.mock.osgi.ReferenceViolationException: Unable to inject mandatory reference 'externalizer' for class com.adobe.cq.wcm.core.components.internal.link.DefaultPathProcessor : no matching services were found.


Below is the code for the test class and related classes. 

 

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

    public static final String COMPONENT_PATH = "component_path";
    public static final String COMPONENT_CONTENT_PATH = "content_path";

    public final static String PAGE_PATH = "page_path";
    private final AemContext ctx = AppAemContext.newAemContextForCore();

    private Title title;

    /**
     * Setup aem context with resource and models.
     */
    @BeforeEach
    void setUp() {
        // Load all sling models to AEM context
        ctx.addModelsForClasses(Title.class);
        // Load Page resource with component to context
        ctx.load().json("/models/TitleImplTest/TitleImplTest.json", PAGE_PATH);
        // Load Component to context for delegation pattern
        ctx.load().json("/models/TitleImplTest/Component.json", COMPONENT_PATH);
        // Set Current path to component under page
        ctx.currentResource(COMPONENT_CONTENT_PATH);

        // Adapt request to Sling Model
        title = ctx.request().adaptTo(Title.class);
    }

    /**
     * Test Title Impl methods.
     */
    @Test
    void testTitleImpl() {
        // Validate all fields/methods
        assertEquals("Explore Process Optimization", title.getText(), "Verify title text");
        assertFalse(title.enableAnchor(), "Verify anchor disabled");
        assertEquals("explore-process-optimization", title.getAnchorID(), "Verify anchor id");
        assertEquals("/jcr:content/root/responsivegrid/container/title", title.getMeta().getComponentRelativePath(), "Verify component relative path");
    }

 

 

 

public static AemContext newAemContextForCore() {
        return new AemContextBuilder().resourceResolverType(ResourceResolverType.JCR_MOCK)
                .plugin(CORE_COMPONENTS).build();
    }

 

 

 

@Delegate(types = com.adobe.cq.wcm.core.components.models.Title.class, excludes = Handled.class)
    @Self @Via(type = ResourceSuperType.class)
    private com.adobe.cq.wcm.core.components.models.Title delegate;

 

 

Appreciate your response.