How to use AEM Mocks in Adobe AEM Project Archetype

Problem

Projects created with the Adobe AEM Project Archteype with Version 17 or lower do not include a dependency to AEM Mocks, but only a dependency to Apache Sling Mocks. This makes it difficult to write unit tests for code that uses the AEM API, because complex objects like Page, PageManager, Asset etc. need to be mocked manually. This article describes how to switch from Sling Mocks to AEM Mocks.

Solution

To switch to AEM Mocks there are three steps. Only the first is mandatory, Step 2 and 3 are optional.

Step 1 - Switch to AEM Mock Dependency (mandatory)

For projects created with Adobe AEM Project Archetype Version 18 this step can be skipped, as the AEM Mocks dependency is already included.

You have to change the dependencies in two POMs to make AEM Mocks available:

pom.xml (Root POM):

Replace

<dependency>
  <groupId>org.apache.sling</groupId>
  <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
  <version>2.3.4</version>
  <scope>test</scope>
</dependency>

with

<dependency>
  <groupId>io.wcm.</groupId>
  <artifactId>io.wcm.testing.aem-mock.junit4</artifactId>
  <version>2.4.4</version>
  <scope>test</scope>
</dependency>

core/pom.xml (Bundle POM):

Replace

<dependency>
  <groupId>org.apache.sling</groupId>
  <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
</dependency>

with

<dependency>
  <groupId>io.wcm.</groupId>
  <artifactId>io.wcm.testing.aem-mock.junit4</artifactId>
</dependency>

Step 2 - Switch to AEM Dependencies Import POM managed by wcm.io (optional, recommended)

AEM Mocks requires a set of Sling-internal dependencies which are not included in the Adobe AEM "Uber" JAR, and are not required to compile against, but are required by AEM Mocks and Sling Mocks to run the unit tests in the mocked environment. AEM Mocks supports all AEM Major Versions since AEM 6.2 and therefore includes these dependencies in the version included in AEM 6.2. If you use AEM 6.3, AEM 6.4 or a newer AEM version you cannot use features that where added since AEM 6.2 and you unit tests may break.

To avoid this you can switch to an "Import POM" with all dependencies requires for a certain AEM version managed by the wcm.io project. Available versions:

To apply this to your project you have to replace:

pom.xml (Root POM):

Replace

<dependency>
  <groupId>com.adobe.aem</groupId>
  <artifactId>uber-jar</artifactId>
  <version>6.3.0</version>
  <classifier>apis</classifier>
  <scope>provided</scope>
</dependency>

with

<dependency>
  <groupId>io.wcm.maven</groupId>
  <artifactId>io.wcm.maven.aem-dependencies</artifactId>
  <version>6.3.0.0002</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

Replace the versions with the AEM and probably service pack version you are using.

Step 3 - Switch to JUnit 5 (optional)

The Adobe AEM Project Archetype is using JUnit 4. It is recommended to start a new project rightaway with JUnit 5 - you can follow the steps from this article to switch to JUnit 5:
Migrate AEM Mocks Unit Tests from JUnit 4 to JUnit 5