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

SOLVED

AEM Java unit test , adapt resource without jcr:title to model ?

RobertBailey1
Level 2
Level 2

In an AEM Java unit test , is it possible to adapt a resource without jcr:title to a model ?

In example below , testEmptyPage() is behaving as expected , but testEmptyPageMissingTitle() is not behaving as expected because it sets pageBean to null ?

In an AEM Java unit test , how can I adapt a resource without jcr:title to a model ?

Thank you and best regards.


********** MyPageBeanModelTest.java **********

@RunWith(MockitoJUnitRunner.class)
public class MyPageBeanModelTest {

    @rule
    public final AemContext context = new AemContext();

    @Mock
    private LiveRelationshipManager liveRelationshipManager;

    @Before
    public void setUp() {
        context.load().json("/mockedJCR/models/structure/page/empty-page.json", "/content/myproject/en/empty-page");
        context.load().json("/mockedJCR/models/structure/page/empty-page-missing-title.json", "/content/myproject/en/empty-page-missing-title");
        context.registerService(LiveRelationshipManager.class, liveRelationshipManager);
    }
    @test
    public void testEmptyPage() {
        System.out.println("----------------------------  START testEmptyPage()  ----------------------------");
        Resource resource = context.resourceResolver().getResource("/content/myproject/en/empty-page/jcr:content");
        PageBeanModel pageBean = resource.adaptTo(PageBeanModel.class);
        System.out.println("resource = " + (resource==null ? "NULL" : resource.toString()));
        System.out.println("pageBean = " + (pageBean==null ? "NULL" : pageBean.toString()));
    }

    @test
    public void testEmptyPageMissingTitle() {
        System.out.println("----------------------------  START (testEmptyPageMissingTitle()  ----------------------------");
        Resource resource = context.resourceResolver().getResource("/content/myproject/en/empty-page-missing-title/jcr:content");
        PageBeanModel pageBean = resource.adaptTo(PageBeanModel.class);
        System.out.println("resource = " + (resource==null ? "NULL" : resource.toString()));
        System.out.println("pageBean = " + (pageBean==null ? "NULL" : pageBean.toString()));
    }
}


********** empty-page.json **********

{
  "jcr:primaryType": "cq:Page",
  "jcr:content": {
    "jcr:primaryType": "cq:PageContent",
    "jcr:title": "unitTestPage",
    "sling:resourceType": "myproject/components/structure/page"
  }
}


********** empty-page-missing-title.json **********

{
  "jcr:primaryType": "cq:Page",
  "jcr:content": {
    "jcr:primaryType": "cq:PageContent",
    "sling:resourceType": "myproject/components/structure/page"
  }
}


********** MyPageBeanModelTest console output **********

----------------------------  START testEmptyPage()  ----------------------------
resource = MockResource [path=/content/myproject/en/empty-page/jcr:content, props=org.apache.sling.testing.resourceresolver.MockValueMap@f54a9a92 : org.apache.sling.testing.resourceresolver.ValueMapDecorator@f54a9a92 : {sling:resourceType=myproject/components/structure/page, jcr:primaryType=cq:PageContent, jcr:title=unitTestPage}]
pageBean = com.project.core.models.components.structure.page.PageBeanModel@3437fc4f
----------------------------  START (testEmptyPageMissingTitle()  ----------------------------
resource = MockResource [path=/content/myproject/en/empty-page-missing-title/jcr:content, props=org.apache.sling.testing.resourceresolver.MockValueMap@dde18880 : org.apache.sling.testing.resourceresolver.ValueMapDecorator@dde18880 : {sling:resourceType=myproject/components/structure/page, jcr:primaryType=cq:PageContent}]
pageBean = NULL
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

 

1 Accepted Solution
Jörg_Hoh
Correct answer by
Employee
Employee

The problem is your SlingModel. And from my point of view making fields optional is rarely the solution to such problems. 

 

From my point of view the problem is the missing registration of the SlingModel classes in the AemContext object. Please check the documentation at https://wcm.io/testing/aem-mock/usage.html#Sling_Models

View solution in original post

0 Replies
Vijayalakshmi_S
Community Advisor
Community Advisor

Hi @RobertBailey1,

Possible reason for model being null could be variables/objects used in the model is null (not letting it to instantiate)

Cross check the same(In particular, check if jcr:title is mandatory injection) or please share the PageBeanModel class if possible to debug further.

SureshDhulipudi
Community Advisor
Community Advisor

for Sling Model class check the defaultInjection Strategy (Constructor Injection and Field level injection)

For jcr:title is mandatory set to optional and try.

defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL

RobertBailey1
Level 2
Level 2

Hi Suresh,

Thank you for suggestion. I tried adding defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL to the model , and also tried adding defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED , unfortunately neither has solved the problem and unit test is reporting pageBean as null when jcr:title missing from loaded content.

 

********** Model with defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL **********

@Model(adaptables = {Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class PageBeanModel implements Serializable {

    @inject
    @Named(JcrConstants.JCR_TITLE)
    @Optional
    private String title;

}

 

********** Model with defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED **********

@Model(adaptables = {Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED)
public class PageBeanModel implements Serializable {

    @inject
    @Named(JcrConstants.JCR_TITLE)
    @Optional
    private String title;

}
SureshDhulipudi
Community Advisor
Community Advisor

can you try like this

@inject
@Named(JcrConstants.JCR_TITLE)
@Optional
@default(values="No Title")
private String title;

or

@inject
@Named(JcrConstants.JCR_TITLE)
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
@default(values="No Title")
private String title;

Jörg_Hoh
Correct answer by
Employee
Employee

The problem is your SlingModel. And from my point of view making fields optional is rarely the solution to such problems. 

 

From my point of view the problem is the missing registration of the SlingModel classes in the AemContext object. Please check the documentation at https://wcm.io/testing/aem-mock/usage.html#Sling_Models

View solution in original post