Solved
AEM @Model newbie - junit tests - @Model doesn't adapt to fake "Resource"
hi folks,
I'm trying to get into using @Models instead of Use classes and Servlets.
I can get the @Models to work o.k. but I'm having trouble with unit tests for them.
I set up a pretend "Resource" with a node with a string property "target" of value "target".
However, I can't map my @Model to it. I just get back "nulls" instead of parameter values.
See Model and Unit Test below.
Any ideas ?
thanks
Fiona
@Model(
// This must adapt from a SlingHttpServletRequest, since this is invoked directly via a request, and not via a resource.
// If can specify Resource.class as a second adaptable as needed
adaptables = { SlingHttpServletRequest.class, Resource.class },
adapters = {RelatedArticleModel.class},
// The resourceType is required if you want Sling to "naturally" expose this models as the exporter for a Resource.
resourceType = RelatedArticleModel.TITLE_RESOURCE_TYPE,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
// name = the registered name of the exporter
// extensions = the extensions this exporter is registered to
// selector = defaults to "models", can override as needed; This is helpful if a single resource needs 2 different JSON renditions
@Exporter(name = "jackson", extensions = "json", options = {
/**
* Jackson options:
* - Mapper Features: http://static.javadoc.io/com.fasterxml.jackson.core/jackson-databind/2.8.5/com/fasterxml/jackson/databind/MapperFeature.html
* - Serialization Features: http://static.javadoc.io/com.fasterxml.jackson.core/jackson-databind/2.8.5/com/fasterxml/jackson/databind/SerializationFeature.html
*/
@ExporterOption(name = "MapperFeature.SORT_PROPERTIES_ALPHABETICALLY", value = "true"),
@ExporterOption(name = "SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value="false")
})
public class RelatedArticleModel {
public static final String TITLE_RESOURCE_TYPE = "xyz/components/content/relatedarticle";
@Self
private SlingHttpServletRequest request;
@ScriptVariable
private ResourceResolver resolver;
@ValueMapValue(optional = false)
private String title;
@ValueMapValue(optional = false)
private String target;
@PostConstruct
// PostConstructs are called after all the injection has occurred, but before the Model object is returned for use.
private void init() {
// do stuff
}
public String getTitle() {
return title;
}
public String getTarget() {
return target;
}
public void setTitle(String title) {
this.title = title;
}
public void setTarget(String target) {
this.target = target;
}
}
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.apache.sling.testing.mock.sling.ResourceResolverType;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import static junitx.framework.Assert.assertEquals;
@ExtendWith({AemContextExtension.class, MockitoExtension.class})
public class RelatedArticleModelTest {
public final AemContext ctx = new AemContext(ResourceResolverType.JCR_MOCK);
private RelatedArticleModel underTest;
@BeforeEach
void setUp() throws Exception {
ctx.addModelsForClasses(RelatedArticleModel.class);
}
@Test
public void testGetTarget() {
Resource relatedArticleResourceContext = ctx.create().resource("/content/relatedarticle",
"sling:resourceType", "xyz/components/content/relatedarticle",
"target", "target");
System.out.println("resource path is " + relatedArticleResourceContext.getPath());
System.out.println("resource type is " + relatedArticleResourceContext.getResourceType());
System.out.println("resource name is " + relatedArticleResourceContext.getName());
System.out.println("resource target from valuemap is " + relatedArticleResourceContext.getValueMap().get("target", String.class));
underTest = relatedArticleResourceContext.adaptTo(RelatedArticleModel.class);
assertEquals("target", underTest.getTarget()); <<< *****Null pointer exception, underTest.getTarget() is null*****
}
}
