AEM Tip: JUnit AemContext Integration with an AEM RepositoryAEM Tip: JUnit AemContext Integration with an AEM Repository

Tech Tips

11 min read

AEM Tip – JUnit AemContext Integration with an AEM Repository

Tags

#AEM

#AEM Tips

#Unit Testing

#Digital Marketing Technology

Share

It’s difficult to imagine a modern software application that can live without JUnit tests. In a previous article on JUnit testing, JUnit Tests for WCMUsePojo Objects, we included a tip involving a project we were working on. For this article, we use the same project and extend the approach with sling models and a direct connection to a real AEM repository.

In our case, we encountered a problem when we had to test a big back-end service that had a lot of dependencies with other services, data, and web content inside a JCR repository. Creating JUnit tests for AEM components and services requires preparing tons of data, so we implemented a solution that helps save time in preparing all of this data. We were able to use a real repository and data prepared in AEM using all of AEM’s capabilities. This solution significantly sped up writing tests and improved the quality of tests.

Connecting a JUnit test to AEM is a no-brainer requiring just a few simple steps:

  1. Download a class package https://github.com/apache/sling-org-apache-sling-testing-sling-mock-oak/tree/master/src/main/java/org/apache/sling/testing/mock/sling/oak
  2. Include the WEB DAV repository factory org.apache.jackrabbit:jackrabbit-jcr2dav dependency in your pom.xml file
  3. Modify the OakMockSlingRepository class from the first step to use the ProxyRepository Connection. Here’s just the changed code:

private SimpleCredentials simpleCredentials;
    private ProxyRepository proxyRepository;
 
@Activate
    protected void activate(BundleContext bundleContext) {
        executor = Executors.newSingleThreadExecutor();
        scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
 
        if (bundleContext.getServiceReference(Executor.class) == null) {
            bundleContext.registerService(Executor.class, executor, null);
        }
 
        try {
            simpleCredentials = new SimpleCredentials("[AEM user]", “[password]”);
            proxyRepository = new ProxyRepository(mode.getPath() + "/crx/server");
 
            Session session = proxyRepository.login(simpleCredentials);
            repository = session.getRepository();
        } catch (Exception e) {
        //TODO
        }
    }
    public Session loginAdministrative(String workspaceName) throws RepositoryException {
        return proxyRepository.login(simpleCredentials);//you possibly want to use admin creds
    }

Now you can declare an AemContext Test Rule in your test cases:

@Rule
public AemContext context = new AemContext(ResourceResolverType.JCR_OAK);

It will use your AEM Repository for tests. Almost anything is possible now, just use a real repository path and adapt to page or sling model:

@Test
public void slingModelTest() throws IOException {    
        Resource resource = context.resourceResolver().
             getResource("/content/blueprint/junit/page");
        Page page = resource.adaptTo(Page.class);
        ComponentSlingModel model = page.getContentResource().
             getChild("main-par/buttoncompone").adaptTo(ComponentSlingModel.class);
//TODO
}

Tips for Additions

Here is a list of nice tips for additions to your tests’ base class that can help you with complex tests:

OSGi configs for the test context

ConfigurationAdmin сonfigurationAdmin = context.getService(ConfigurationAdmin.class);
Dictionary<String, Object> properties = new Hashtable<String, Object>();
properties.put("[key]", "value");
сonfigurationAdmin.getConfiguration("configuration PID").update(properties);
ConfigurationAdmin сonfigurationAdmin = context.getService(ConfigurationAdmin.class);
Dictionary<String, Object> properties = new Hashtable<String, Object>();
properties.put("[key]", "value");
сonfigurationAdmin.getConfiguration("configuration PID").update(properties);

Run modes for the test context

MockSlingSettingService settingService = (MockSlingSettingService)
context.getService(SlingSettingsService.class);
Set<String> runModes = new HashSet<>();
Collections.addAll(runModes, "author", "qa");
settingService.setRunModes(runModes);

Inject and Activate services (any of your real services or external services like GenericListAdapterFactory)

context.registerInjectActivateService(new
         com.adobe.acs.commons.genericlists.impl.GenericListAdapterFactory());
context.registerInjectActivateService(new MyCacheServiceImpl());

Register any AEM Mock Service without activation, just to satisfy dependencies

context.registerService(CryptoSupport.class, new MockCryptoSupport());

Supply the context and sling models with sling request related objects

Resource mockRequestRes = context.resourceResolver().getResource("/[path]/anypage");
context.request().setResource(resource);
context.request().setServletPath("[sevlet path]");
 
Page page = anyResource.adaptTo(Page.class);
anyExampleModel.setRequest(context.request());
anyExampleModel.setCurrentPage(page);
anyExampleModel.setSlingScriptHelper(context.slingScriptHelper());

Author: Peter Zhuravlev

Resource Hub

Our Latest Stories & Industry Insights

View Resource Hub

Dark geometric prism with glowing teal outlines and abstract digital particles on a dark background.

Content Fragments in Depth. CF Management Workflow. Part 3.3

7 min read

May 24, 2023

#AEM #Content Fragments #Digital Experience #Digital Marketing Technology

Blue wireless computer mouse next to a laptop keyboard with pink backlit keys on dark surface.

Content Fragments in Depth. AEM Workflow Management. Part 3.1

7 min read

May 10, 2023

#AEM #Content Fragments #Digital Experience #Digital Marketing Technology

3D blue cubes connected by glowing pink lines on a dark surface representing a digital network.

AEM Content Fragments in Depth. Custom Schemas. Part 2

10 min read

May 3, 2023

#AEM #Content Fragments #Digital Experience #Digital Marketing Technology

Empty picture frame with red and green edges on teal textured wall.

How to Add Image Management to an AEM TouchUI Dialog: Tutorial

16 min read

October 12, 2021

#AEM #Open Source #Touch UI #Digital Marketing Technology #EXADEL Authoring Kit For AEM

Two people sitting at a table with a laptop.

Let’s make your next project faster, safer, smarter.

Get In Touch