Expand my Community achievements bar.

July 31st AEM Gems Webinar: Elevate your AEM development to master the integration of private GitHub repositories within AEM Cloud Manager.

JUnit Test Cases for Sling Models based on Delegation Pattern


Level 2

I am trying to write jUnit test cases for custom teaser component which extends the core Teaser component using the Delegation Pattern for Sling Models using "@Self @Via(type=ResourceSuperType.class)" as specified here: https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models
When I try to set the context (io.wcm.testing.mock.aem.junit5.AemContext) and adapt the context's request (I've tried resource as well) to the model I have created (like the "PageHeadline" from the example), I am getting a NullPointerException.

I am using AEM and trying to run test cases in JUnit 5

1 Accepted Solution


Correct answer by
Level 2

I've managed to find a solution.


Basically instead of relying on injection during the Unit test I've used Mockito and FieldSetter.setField


The only change to the source code would be to ensure the defaultInjectionStrategy was Optional. Not ideal but minimal


First we need to adapt the request to core Teaser.class

Teaser coreTeaser = request.adaptTo(Teaser.class);

Then we adapt the request to our custom teaser

CustomTeaser underTest = request.adaptTo(CustomTeaser.class);

Then we set the field that's not injecting

try {
FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("teaser"), coreTeaser);
} catch (NoSuchFieldException e) {


Specific to Teaser I also had to set some SlingBindings so that @ScriptVariables were set when adapting the request to Teaser.class


request = context.request();

Component component = mock(Component.class);
Style style = mock(Style.class);
SlingBindings slingBindings = (SlingBindings) request.getAttribute(SlingBindings.class.getName());
slingBindings.put(WCMBindingsConstants.NAME_COMPONENT, component);
slingBindings.put(WCMBindingsConstants.NAME_CURRENT_STYLE, style);
request.setAttribute(SlingBindings.class.getName(), slingBindings);


Following may only be specific to our POM setup but thought I'd add for completeness 


I also had to bump aem mock junit5 dependency to



View solution in original post

36 Replies


Community Advisor


You need to use one more adaptable to adapt Teaser Component 


@Model(adaptables = SlingHttpServletRequest.class, adapters = {Teaser.class, CustomTeaser.class}, resourceType = TeaserImpl.RESOURCE_TYPE)


Use CustomeTaeser to adapt to Junit test cases.


It will not cover 100% coverage but you will be able to write test cases for custom functionality.

Arun Patidar


Level 2
I tried adding that additional adapter class and I'm still getting null when I try to adapt the context request to my CustomTeaser


Level 2
Thank you Arun! I resolved the issue with the help of your sample code. I had missed out the "defaultInjectionStrategy=DefaultInjectionStrategy.OPTIONAL" option in my custom model which in turn caused an error during init when being initialised through the test case.


Level 2
Hi Arun. Is it possible to create JUnit test cases even if we use one of the core component Teaser's methods (say like isActionsEnabled or getActions) inside our CustomTeaser's @PostConstruct method? Because when I try to do that I am not able adapt the context without encountering a NullPointer inside the method annotated with @PostConstruct in CustomTeaser.


Level 1

Hi. I am having the same problem here. The core component property is always null in the custom implementation. And making it Optional just skips the instantiation of it.


Level 1
Have you fixed the null Teaser object in your test when you did adaptTo? I'm trying to do the same with an extesion of the Image core component but I'm still having my image field (the one with the @Deleted Account) null.


Community Advisor
Hi,I am also not able to get all the properties of Teaser in junit test class, I was able to manage to write test cases only for custom properties using CustomTeaser class adapter. If you will adapt model to Teaser, you will see NPE.

Arun Patidar


Level 4

hi @arunpatidar - were you able to properties of Teaser in junit test class,


Level 1

I don't see the accepted solution as a solution. The model fails to adapt.

Making the field in the model optional hides the issue, but this too is not a solution (it just masks the problem).


Level 2
I also do not see this as an acceptable answer. My Teaser via the ResourceSuperType is always null

Hi Arun_PatidarEven I am facing a similar issue, can below is my component model

@Model(adaptables = SlingHttpServletRequest.class, adapters = {List.class, ComponentExporter.class, TeaserListModel.class}, resourceType = TeaserListModel.TEASER_LIST_RESOURCE_TYPE,defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

public class TeaserListModel implements List {

public static final String TEASER_LIST_RESOURCE_TYPE = "/components/template/teaserlist";



here is my Junit Test Case :

public abstract class AbstractTest {

public final void setUpTest() {

this.resolver = aemContext.resourceResolver();
this.request = aemContext.request();
this.response = aemContext.response();
this.pageManager = aemContext.pageManager();

String contentFilePath = this.getContentFilePath();
if (StringUtils.isNotEmpty(contentFilePath)) {
this.aemContext.load().json(contentFilePath, "/content");


class TeaserListModelTest extends AbstractTest {

protected String getContentFilePath() {
//loading the json here
return "/models/template/TeaserListModelTest.json";

void testTeaserListModelValues() {

//aemContext is the context
Resource myResource = aemContext.resourceResolver().getResource("/TeaserList");
TeaserListModel model = myResource.adaptTo(TeaserListModel.class);


TeaserListModelTest.json file

"TeaserList": {
"jcr:primaryType": "nt:unstructured",
"showModificationDate": "true",
"jcr:createdBy": "admin",
"tagsMatch": "any",
"linkItems": "true",
"orderBy": "title",
"jcr:lastModifiedBy": "admin",
"jcr:created": "Mon Jul 12 2021 10:40:37 GMT-0400",
"sortOrder": "asc",
"id": "567",
"maxItems": "4",
"showDescription": "true",
"jcr:lastModified": "Mon Jul 12 2021 10:41:05 GMT-0400",
"childDepth": "4",
"listFrom": "children"

I am getting a NullPointer at TeaserListModel model = myResource.adaptTo(TeaserListModel.class);





Community Advisor

can you check if resource exists?

Resource myResource = aemContext.resourceResolver().getResource("/TeaserList");


In json the resource type is missing as well.

Arun Patidar


Employee Advisor

have you registered the Sling model for the core teaser component as well to the context?




Level 2
Yes. I have included it in the context as follows: context.addModelsForClasses(com.adobe.cq.wcm.core.components.models.Teaser.class);


Level 2
Yes. I have included it in the context as follows:context.addModelsForClasses(com.adobe.cq.wcm.core.components.models.Teaser.class);