JUnit Test Cases for Sling Models based on Delegation Pattern

Avatar

Avatar

gomatis80521865

Avatar

gomatis80521865

gomatis80521865

24-12-2019

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 6.5.2.0 and trying to run test cases in JUnit 5

junit models sling

Accepted Solutions (1)

Accepted Solutions (1)

Avatar

Avatar

Rick_Holdsworth

Avatar

Rick_Holdsworth

Rick_Holdsworth

09-02-2021

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) {
e.printStackTrace();
}

 

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

@BeforeEach

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

<artifactId>io.wcm.testing.aem-mock.junit5</artifactId>
<version>4.0.0</version>

 

Answers (5)

Answers (5)

Avatar

Avatar

Arun_Patidar

MVP

Total Posts

3.0K

Likes

1.1K

Correct Reply

861

Avatar

Arun_Patidar

MVP

Total Posts

3.0K

Likes

1.1K

Correct Reply

861
Arun_Patidar
MVP

24-12-2019

Hi,

You need to use one more adaptable to adapt Teaser Component 

e.g.

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

Avatar

Avatar

Jörg_Hoh

Employee

Total Posts

3.0K

Likes

996

Correct Reply

1.0K

Avatar

Jörg_Hoh

Employee

Total Posts

3.0K

Likes

996

Correct Reply

1.0K
Jörg_Hoh
Employee

27-06-2020

Anyway, next to the working solution this seems to be a short-coming of the mocking libraries. Can you create a minimal testcase (at best without any AEM dependency) and post it to the sling-developer list?

Avatar

Avatar

robertod4340573

Avatar

robertod4340573

robertod4340573

26-06-2020

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.

Avatar

Avatar

thienm92844762

Avatar

thienm92844762

thienm92844762

02-01-2020

Thank you so much!

Avatar

Avatar

Jörg_Hoh

Employee

Total Posts

3.0K

Likes

996

Correct Reply

1.0K

Avatar

Jörg_Hoh

Employee

Total Posts

3.0K

Likes

996

Correct Reply

1.0K
Jörg_Hoh
Employee

27-12-2019

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

 

Jörg