Expand my Community achievements bar.

Unable to load JSON file using AEMContext for AEM Sling Model

Avatar

Level 9

I am trying to create a JUNIT for my sling model class. I am following - https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-wknd-tutorial-devel.... As per this doc I am using AemContext to load the json file but I get Null when I try to read values.

 

JUNIT

 

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.techcombank.core.constants.TestConstants;
import com.techcombank.core.testcontext.AppAemContext;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import org.apache.sling.api.resource.Resource;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import com.day.cq.wcm.api.WCMMode;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

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

public class FeatureListModelTest  {

    private final AemContext ctx = AppAemContext.newAemContext();
   
    FeatureListModel featureModel;
   

    @BeforeEach
    void setUp() throws Exception {

        ctx.load().json("/content/mysite/en/featurelist.json", "/content");
        ctx.addModelsForClasses(FeatureListModel.class);
        featureModel = getModel("/content/jcr:content/root/feature");
    }
   
     @Test
        void getFeaturePath() {
            final String expected = "/content/dam/mysite/logo.jpg";
            assertEquals(expected, featureModel.getFeaturePath());
        }
     
     private FeatureListModel getModel(String currentResource) {
            ctx.request().setAttribute(WCMMode.class.getName(), WCMMode.EDIT);
            ctx.currentResource(currentResource);
            FeatureListModel fm = ctx.currentResource().adaptTo(FeatureListModel.class);
            return fm;
        }
}

Here is my json that is placed in resource path

 

{
    "featureList": {
        "jcr:primaryType": "cq:PageContent",
        "jcr:createdBy": "admin",
        "jcr:title": "feature",
        "jcr:created": "Tue Jun 01 2023 21:26:54 GMT+0530",
        "changeFrequency": "always",
        "cq:lastModified": "Tue Jun 06 2023 22:28:27 GMT+0530",
        "featureTitle": "Hello",
        "sling:resourceType": "mywebsite/components/structure/base-page",
        "cq:lastModifiedBy": "admin"
    }
}

 

It seems everything correct but I am not sure why I am getting Null value in modelobject.

 
12 Replies

Avatar

Level 4

Three Things :

1. private final AemContext aemContext = new AemContext();

2. This is incorrect : 

 aemContext.addModelsForClasses(FeatureListModelTest.class);

Correct Syntax : 

 aemContext.addModelsForClasses(FeatureListModel.class);

Where FeatureListModel, is the class you are trying to write Junit for .

3, Incorrect :

featureModel = aemContext.request().adaptTo(FeatureListModelTest.class);

 Correct Syntax :

featureModel = aemContext.request().adaptTo(FeatureListModel.class);

Avatar

Level 9

Sorry, I changed for debugging purpose. Now I  changed the actual model class but I still I get the NULL on featureModel object.

Avatar

Level 4

Did you update at both places ?

Can you post the updated code now.

 

Also I believe the path to your resource file is incorrect

 aemContext.load().json("/content/mywebsite/en/featurelist.json", "/featurelistComponent");

"/content/mywebsite/en/featurelist.json"  --> doesnt look like resource path where your json might be placed.

Avatar

Level 9

yes, I updated my code. This directly (/content/mywebsite/en/featurelist.json) is folder I maintain in src/test/resirces folder 

Avatar

Community Advisor

Hello @Mario248 ,
Is your FeatureListModel using any core Model Class? I mean are you using a sling delegation pattern? 

Avatar

Level 9

yes, here is my FeatureListModel class

 

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL, adapters = FeatureListModel .class)

public class FeatureListModel {
..

}

Avatar

Community Advisor

Hello @Mario248 ,
Have you tried with. 

aemContext.currentResource().adaptTo(FeatureListModel.class);

instead of aemContext.request()?

 

If so, or still it's the null then the problem should be in your Json Resource. You need to provide the correct Json on that case based on your annotation.
Also, mention if you inject any Service into your model class. If so initialize those using @Mock in your test class.

Avatar

Level 4

@Mario248 

Exactly since your adaptable is resource in SlingModel, you should be adapting to current Resource and not request.

 

@Model(adaptables = Resource.class

instead of 

featureModel = aemContext.request().adaptTo(FeatureListModel.class);

try using

aemContext.currentResource("/featurelistComponent/featureList");
aemContext.currentResource().adaptTo(FeatureListModel.class);

Avatar

Level 9

I changed the logic to resource (updated the code)but still it is failed. I see weird issue, it worked once and then it keep on failing. Is it because of resource file that we are loading ?

Avatar

Community Advisor

@Mario248 I think, YES it is. There is no shortcut solution for this without seeing the actual Model class. You just need to check this out.

Avatar

Level 9

@Sady_Rifat - I actually shared the same code to my other team member. It worked there without any issue. Tried in other Windows and Mac machine, it worked as expected. What could be the issue in my local ? Tried compare java and maven version and everything seems to be okay. Any other area or config that I should check ?

Avatar

Community Advisor

If the same code works on other machines then the problem might be in your dependency. Just delete your .m2 folder and try to resolve and re-run again. Hope it will solve your problem.