Expand my Community achievements bar.

Join us in celebrating the outstanding achievement of our AEM Community Member of the Year!
SOLVED

Sling Model Unit Testing

Avatar

Level 1

I created a Sling Model class for my component to get the root page and access all the child pages of that root page. Then how to do a unit testing for my sling model by using Junit5 and AEM Mocks.

 

 

 

 

 

 

1 Accepted Solution

Avatar

Correct answer by
Employee

Hi @nats ,

 

Here is the approach which you can go through step by step to do unit testing for the sling model by using Junit5 and AEM Mocks . 

 

->Make sure your project is set up with the necessary dependencies for JUnit 5 and AEM Mocks. You can add the required dependencies to your project's Maven or Gradle build file.
->Ensure that your Sling Model class is implemented correctly and has the necessary logic to retrieve the root page and access child pages.
->Create a JUnit 5 test class for your Sling Model. This class will be responsible for testing the behavior of your Sling Model.
->In your test class, use AEM Mocks to set up a mock AEM environment that simulates the AEM context. This includes mock requests, resource resolver, and other AEM-specific objects.
->Set up a mock AEM page structure with a root page and child pages that your Sling Model will use during testing.
->Write test methods in your test class to test the behavior of your Sling Model. Use JUnit 5 assertions to verify that the Sling Model behaves as expected.

Sharing an example of how to write a simple unit test for a Sling Model that retrieves child pages under a root page.

Assuming you have the following Sling Model class that retrieves child pages:

@Model(adaptables = SlingHttpServletRequest.class)
public class MyComponentModel {

    @Inject
    private PageManager pageManager;

    private List<Page> childPages;

    @PostConstruct
    protected void init() {
        // Get the root page (assumed to be the current page in this example)
        Page currentPage = pageManager.getContainingPage(request.getResource());

        // Get the child pages of the root page
        childPages = currentPage.getChildren();
    }

    public List<Page> getChildPages() {
        return childPages;
    }
}

 

->let's create a test class for this Sling Model.

import io.wcm.testing.mock.aem.junit5.AemContext;
import org.apache.sling.api.SlingHttpServletRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Reference;

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

@ExtendWith(AemContextExtension.class)
public class MyComponentModelTest {

    private MyComponentModel myComponentModel;

    @BeforeEach
    void setUp(AemContext context, SlingHttpServletRequest request) {
        // Set up your mock AEM context
        // Example: Set up a mock page structure with a root page and child pages
        Page rootPage = context.create().page("/content/mysite");
        context.create().page(rootPage, "child1");
        context.create().page(rootPage, "child2");

        // Create an instance of your Sling Model
        myComponentModel = new MyComponentModel();
        myComponentModel.pageManager = mock(PageManager.class);

        // Set up mock behavior for PageManager to return the root page
        when(myComponentModel.pageManager.getContainingPage(request.getResource())).thenReturn(rootPage);
    }

    @Test
    void testGetChildPages() {
        // Call the init() method to trigger the retrieval of child pages
        myComponentModel.init();

        // Get the list of child pages from the Sling Model
        List<Page> childPages = myComponentModel.getChildPages();

        // Assert that the list of child pages is not null and contains the expected number of pages
        assertNotNull(childPages);
        assertEquals(2, childPages.size());
    }
}

 

Hope this helps !

View solution in original post

2 Replies

Avatar

Correct answer by
Employee

Hi @nats ,

 

Here is the approach which you can go through step by step to do unit testing for the sling model by using Junit5 and AEM Mocks . 

 

->Make sure your project is set up with the necessary dependencies for JUnit 5 and AEM Mocks. You can add the required dependencies to your project's Maven or Gradle build file.
->Ensure that your Sling Model class is implemented correctly and has the necessary logic to retrieve the root page and access child pages.
->Create a JUnit 5 test class for your Sling Model. This class will be responsible for testing the behavior of your Sling Model.
->In your test class, use AEM Mocks to set up a mock AEM environment that simulates the AEM context. This includes mock requests, resource resolver, and other AEM-specific objects.
->Set up a mock AEM page structure with a root page and child pages that your Sling Model will use during testing.
->Write test methods in your test class to test the behavior of your Sling Model. Use JUnit 5 assertions to verify that the Sling Model behaves as expected.

Sharing an example of how to write a simple unit test for a Sling Model that retrieves child pages under a root page.

Assuming you have the following Sling Model class that retrieves child pages:

@Model(adaptables = SlingHttpServletRequest.class)
public class MyComponentModel {

    @Inject
    private PageManager pageManager;

    private List<Page> childPages;

    @PostConstruct
    protected void init() {
        // Get the root page (assumed to be the current page in this example)
        Page currentPage = pageManager.getContainingPage(request.getResource());

        // Get the child pages of the root page
        childPages = currentPage.getChildren();
    }

    public List<Page> getChildPages() {
        return childPages;
    }
}

 

->let's create a test class for this Sling Model.

import io.wcm.testing.mock.aem.junit5.AemContext;
import org.apache.sling.api.SlingHttpServletRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Reference;

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

@ExtendWith(AemContextExtension.class)
public class MyComponentModelTest {

    private MyComponentModel myComponentModel;

    @BeforeEach
    void setUp(AemContext context, SlingHttpServletRequest request) {
        // Set up your mock AEM context
        // Example: Set up a mock page structure with a root page and child pages
        Page rootPage = context.create().page("/content/mysite");
        context.create().page(rootPage, "child1");
        context.create().page(rootPage, "child2");

        // Create an instance of your Sling Model
        myComponentModel = new MyComponentModel();
        myComponentModel.pageManager = mock(PageManager.class);

        // Set up mock behavior for PageManager to return the root page
        when(myComponentModel.pageManager.getContainingPage(request.getResource())).thenReturn(rootPage);
    }

    @Test
    void testGetChildPages() {
        // Call the init() method to trigger the retrieval of child pages
        myComponentModel.init();

        // Get the list of child pages from the Sling Model
        List<Page> childPages = myComponentModel.getChildPages();

        // Assert that the list of child pages is not null and contains the expected number of pages
        assertNotNull(childPages);
        assertEquals(2, childPages.size());
    }
}

 

Hope this helps !

Avatar

Community Advisor

If you take a look at this detailed 1 hour tutorial on how to setup AEM mocks for your JUNIT5 project, it should demystify your confusion about AEM sling models unit tests, and how to actually do it.
https://www.youtube.com/watch?v=g5x6F8bUHj8&ab_channel=AEMGEEKS

If you search for youtube tutorials for this topic, you should be able to educate yourself and learn more about how this is done.