Blogs > Unit Testing in AEM
AEM Sites
Unit Testing in AEM
| February 10, 2023Hi, hope you are doing well. Welcome to another blog.
What is Unit Testing
Unit testing in Java is the process of testing individual methods or classes in isolation to verify their correctness. It ensures that each unit of code works as expected, improving reliability and supporting Test-Driven Development (TDD). Frameworks like JUnit and TestNG are commonly used for writing and automating unit tests using assertions to validate expected outputs.For unit testing in java a framework is used called Junit 5.
Lets have a look on how we can perform unit testing in AEM for that we will take the example of sling model and perform unit testing on it. We are using Junit5 framework specifically.
I have a component in which i have title, description and a multifield naming tags in which we can add multiple tags and below is the sling model for the component
package com.infodales.core.models;
import com.infodales.core.pojo.SamplePojo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import javax.inject.Inject;
import java.util.List;
@Model(adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class SampleModel {
@ValueMapValue
private String title;
@Inject
private List<SamplePojo> castInfo;
public String getTitle() {
return title;
}
public List<SamplePojo> getCastInfo() {
return castInfo;
}
}
And below is the pojo class "SamplePojo"
package com.infodales.core.pojo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
@Model(adaptables = Resource.class)
public class SamplePojo {
@ValueMapValue
private String cardTitle;
@ValueMapValue
private String cardImage;
public String getCardTitle() {
return cardTitle;
}
public String getCardImage() {
return cardImage;
}
}
In the above code we need to test the getter's and setter's of the fields, So to write the Junits for the above code we will create a class called SampleModelTest, In that we will be using "AemContextExtension" it is a JUnit 5 extension provided by the AEM Mocks library (io.wcm.testing.mock.aem.junit5). It is used to simplify and enhance unit testing of Adobe Experience Manager (AEM) components, services, and Sling models by automatically managing an instance of AemContext.
Also we need to generate the json of the component that we have created as i have create the card component which has one textfield for title and one multifield inside that multifield we have cardTitle and cardImage, below is the json for that, this json needs to kept in the code under the resources folder under test package
Below is the final Test class for our class.
package com.infodales.core.models;
import com.infodales.core.pojo.SamplePojo;
import com.infodales.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.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static junit.framework.Assert.assertEquals;
@ExtendWith(AemContextExtension.class)
public class SampleModelTest {
private final AemContext aemContext = AppAemContext.newAemContext();
private SampleModel sampleModel;
@BeforeEach
void setUp() {
aemContext.addModelsForClasses(SampleModel.class);
aemContext.load()
.json("/content/techcombank/web/vn/en/samplejson.json", "/content");
aemContext.currentResource("/content/sample");
Resource resource = aemContext.request().getResource();
sampleModel = resource.adaptTo(SampleModel.class);
}
@Test
void testTitle() {
String expectedTitle = "Companies";
assertEquals(expectedTitle, sampleModel.getTitle());
}
@Test
void testCastInfo() {
List castInfo = sampleModel.getCardInfo();
SamplePojo samplePojo = castInfo.get(0);
String ExpectedCardTitle = "Infodales";
assertEquals(ExpectedCardTitle, samplePojo.getCardTitle());
String ExpectedCardImage = "/content/dam/Infodales/actress/Infodales.jpg";
assertEquals(ExpectedCardImage, samplePojo.getCardImage());
}
}
-
In the above code first of all we need to annotate our class with @ExtendWith(AemContextExtension.class) it Integrates AEM Mocks into JUnit 5.
-
Next is we have initialize AEM Context and SampleModel.AppAemContext.newAemContext() is a custom method (from AppAemContext) that creates an AemContext instance.
-
Next we added the setup method it runs before each test method, inisde that method
-
First we have loaded test data from a JSON file (samplejson.json), simulating content in AEM.
-
We have registered SampleModel as a Sling model using addModelsForClasses().
-
Next is we have set the current resource to /content/sample, meaning sampleModel adapts from this resource.
-
The method adaptTo(SampleModel.class) Converts the resource into a SampleModel instance.
-
Now the json has adapted to our sling model.
-
-
@Test it is used to mark a method as test method in testTitle() method we are checking weather our expected value is similar to that of the value form the json for that we use assertEquals method
-
Similarly in the testCastInfo() method we are testing card title and cardImage values weather they are similar to that of present in the json as in json we only added one value so we will test that only.
Now we will run the junit class by clicking on run button as shown in the below image
As you can see the above test cases have passed.
Thanks for reading 😄