Expand my Community achievements bar.

junit testing for custom component extending core content fragment model

Avatar

Level 2

I am not able to write junit for following custom model class extending content fragment.

content fragment object is always coming null, 

Could anyone tried this before? How to write this junit for custom component model delegating to content fragment model?

 

Sling model Interface : 

package com.myproj.core.models;

import com.adobe.cq.wcm.core.components.models.contentfragment.ContentFragment;

public interface TestContentFragment extends ContentFragment {

String getCfName();
}

 

Sling model Impl class:

package com.myoroj.core.models.impl;

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.models.contentfragment.ContentFragment;
import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData;
import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;
import com.myproj.core.models.TestContentFragment;
import lombok.experimental.Delegate;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Via;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.via.ResourceSuperType;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Model(adaptables = SlingHttpServletRequest.class, adapters = {TestContentFragment.class, ComponentExporter.class}, resourceType = TestContentFragmentImpl.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class TestContentFragmentImpl implements TestContentFragment {
@Self
@Via(type = ResourceSuperType.class)
@Delegate(excludes = TestContentFragmentImpl.Exclusion.class)
private ContentFragment contentFragment;

static final String RESOURCE_TYPE ="/myproj/components/test-cf" ;
@Override
public String getCfName() {

String name= String.valueOf(contentFragment.getElements().get(0).getValue());
return name;

}

interface Exclusion {

}

}

Test class:

 

package com.myproj.core.models.impl;

import com.adobe.cq.wcm.core.components.models.contentfragment.ContentFragment;
import com.myproj.core.models.TestContentFragment;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;
import junitx.util.PrivateAccessor;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.internal.util.reflection.FieldSetter;
import org.mockito.junit.jupiter.MockitoExtension;

import static junitx.framework.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;

@ExtendWith({AemContextExtension.class, MockitoExtension.class})
class TestContentFragmentImplTest {
private final AemContext ctx = new AemContext();

@BeforeEach
void setUp() throws NoSuchFieldException {
ctx.addModelsForClasses(TestContentFragment.class);
ctx.load().json("/com/myproj/core/models/impl/TestContentFragmentImpl.json", "/content");
ctx.load().json("/com/myproj/core/models/impl/TestContentFragmentImplcf.json", "/resource1");


}

@Test
void getName() throws NoSuchFieldException {
String expected = "test";

ContentFragment coreCf = mock(ContentFragment.class);
TestContentFragmentImpl underTest = ctx.request().adaptTo(TestContentFragmentImpl.class);
PrivateAccessor.setField(underTest, "contentFragment", coreCf);

ctx.currentResource("/content/test_cf");
Assertions.assertNotNull(coreCf);
assertEquals(expected, underTest.getCfName());

}

 Json files : 

 

{
"test_cf": {
"jcr:primaryType": "nt:unstructured",
"jcr:createdBy": "admin",
"paragraphScope": "all",
"jcr:lastModifiedBy": "admin",
"jcr:created": "Mon Nov 07 2022 11:24:57 GMT+0530",
"text": "test",
"variationName": "master",
"jcr:lastModified": "Mon Nov 07 2022 12:16:49 GMT+0530",
"sling:resourceType": "myproj/components/test-cf",
"displayMode": "multi",
"fragmentPath": "/resource1/dam/content-fragment"
}
}

Content Fragment Json:
{
"dam": {
"content-fragment": {
"jcr:primaryType": "dam:Asset",
"jcr:mixinTypes": ["mix:referenceable", "mix:versionable"],
"jcr:createdBy": "admin",
"jcr:versionHistory": "005125cd-cc74-4db6-98ba-9e9dae34b958",
"jcr:predecessors": ["3f83c7af-93a1-4612-ab59-38fc5ced717c"],
"jcr:created": "Mon Nov 07 2022 12:16:23 GMT+0530",
"jcr:baseVersion": "3f83c7af-93a1-4612-ab59-38fc5ced717c",
"jcr:isCheckedOut": true,
"jcr:uuid": "3fec75bd-9281-4b6c-9051-eda63ef59f2e",
"jcr:content": {
"jcr:primaryType": "dam:AssetContent",
"jcr:title": "test",
"jcr:lastModifiedBy": "admin",
"contentFragment": true,
"cq:name": "test",
"jcr:lastModified": "Mon Nov 07 2022 12:16:29 GMT+0530",
"lastFragmentSave": "Mon Nov 07 2022 12:16:29 GMT+0530",
"cq:parentPath": "/content/dam/myproj/en/articles/content-fragment",
"renditions": {
"jcr:primaryType": "nt:folder",
"jcr:createdBy": "admin",
"jcr:created": "Mon Nov 07 2022 12:16:23 GMT+0530"
},
"related": {
"jcr:primaryType": "nt:unstructured"
},
"metadata": {
"jcr:primaryType": "nt:unstructured",
"jcr:mixinTypes": ["cq:Taggable"]
},
"data": {
"jcr:primaryType": "nt:unstructured",
"cq:model": "/conf/myproj/settings/dam/cfm/models/test123",
"master": {
"jcr:primaryType": "nt:unstructured",
"jcr:mixinTypes": ["dam:cfVariationNode", "cq:Taggable"],
"name@LastModified": "Mon Nov 07 2022 12:16:29 GMT+0530",
"name": "test"
}
}
}
}
}
}


 

3 Replies

Avatar

Community Advisor

@KajalInamdarEy  Isn't the following line setting up the contentFragment field value in test? 

 

PrivateAccessor.setField(underTest, "contentFragment", coreCf);

I can run the test class you provided and noticed that the contentFragment value is set, but getting a different error though - java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 because of the mock contentFragment object. 

Avatar

Level 2

Yes, I am also getting empty Content fragment, can you suggest how should we populate this content fragment, as in my resource json , fragment path for content fragment json is already present.