Why JUnit?
- It finds logical bugs early in the code, which makes our code more reliable.
- JUnit is useful for developers, who work in a test-driven environment as it forces them to develop more readable, reliable and bug-free code which builds confidence during development.
- It increases the productivity of the programmer and the stability of the program code, which in turn, reduces the stress on the programmer and the time spent on debugging.
NOTE: context.loader is used to load page content in JSON format and it allows us to test the code against it.
Now let us see how to write JUnit in AEM using SlingContext. Below is the sample sling model for which we’ll be writing JUnit.
Sample sling model:
import javax.inject.Inject;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
@Model(adaptables = {Resource.class})
public class UserDetails {
@Inject @Optional
private String firstName;
@Inject @Optional
private String lastName;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
Getting started with JUnit:
Prerequisites: The following are the prerequisites before getting started.- Add the following dependencies to the POM.xml
<dependencies>
…
<!– Testing –>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.4.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.25.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.25.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.wcm</groupId>
<artifactId>io.wcm.testing.aem-mock.junit5</artifactId>
<version>2.4.4</version>
<scope>test</scope>
</dependency>
…
</dependencies>
- Copy-paste the page JSON (let us say, content.json) to src/main/resources folder.
How to get JSON data?
JSON data can be obtained by exporting page content using .infinity.json extension.For example, let us consider that we are working on user details component in my-page ( http://localhost:4502/editor.html/content/we-retail/us/en/my-page.html ).
We are good to get started now after performing the above steps. Below is the JUnit for the above sling model:
JUnit:
import static org.junit.Assert.assertEquals;In the above JUnit,
import org.apache.sling.api.resource.Resource;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class UserDetailsTest {
private UserDetails userDetails;
private Resource resource;
private final String myPagePath = “/content/we-retail/us/en/my-page”;
@Rule
public final SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK);
@Before
public void setUp() throws Exception {
context.load().json(“/content.json”, myPagePath);
context.addModelsForPackage(“<mention-your-package-here>”);
}
@Test
public void getFirstNameTest() throws Exception {
resource = context.resourceResolver()
.getResource(myPagePath + “/jcr:content/root/responsivegrid/userdetails”);
userDetails = resource.adaptTo(UserDetails.class);
assertEquals(userDetails.getFirstName(), “Lavanya”);
}
@Test
public void getLastNameTest() throws Exception {
resource = context.resourceResolver()
.getResource(myPagePath + “/jcr:content/root/responsivegrid/userdetails”);
userDetails = resource.adaptTo(UserDetails.class);
assertEquals(userDetails.getLastName(), “Malyala”);
}
}
- addModelsForClasses registers the Sling Model to be tested, into the mock SlingContext, so it can be instantiated in the @Test methods.
- load().json loads resource structures into the mock context, allowing the code to interact with these resources as if they were provided by a real repository. The resource definitions in the file content.json are loaded into the mock JCR context under /content/we-retail/us/en/my-page.
- resourceResolver().getResource(myPagePath + “/jcr:content/root/responsivegrid/userdetails”) gets userdetails resource from JSON and asserts it respectively.
- assertEquals asserts the expected value matches the value returned by the userdetails Sling Model object. If these values are not equal, the test will fail. Otherwise, it will pass.
How to get the code coverage?
Code coverage is the amount of source code covered by unit tests. Install the EclEmma plugin from the marketplace to get the code coverage.Link for installation steps: EclEmma – Installation
Once the above plugin is installed, we can right-click on the Junit and Run As -> Junit Test.
We’ll see the above Junit as a success (in Junit tab), indicated by the green color status bar. Otherwise, it’ll be shown in red color. Also, we will get the code coverage details in Coverage tab as shown in the below screenshots:
No comments:
Post a Comment
If you have any doubts or questions, please let us know.