Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

[AEM Gems Webinar] Accelerating Experience Manager as a Cloud Service development with Rapid Development Environments

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:
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

32 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.


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.


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


Level 1

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);





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);


Level 1
Hello! Have you resolved the issue? I mean the case when we use one of the core component Teaser's methods? I also have a NullPointer.


Level 1

I have the same issue. I needed to declare the delegate proxy core component (Page in my case) as optional in my sling model as it is not resolved in the unit test (should not be optional in the real use case). Is a pity because my custom logic is simply a fallback of the core component one. I would like to have the object not null in my unit test so I will drop the Optional annotation for the field.