aem-Simplify unit testing with aemcontextcallback

AEM: Simplify unit testing with AemContextCallback

For testing (you do this, right?) your AEM project, most probably, you use AEM Mocks from wcm.io. This is a powerful library, which makes your life easier when it comes to testing Sling Models, Servlets, other classes which work with Page and other entities from AEM.

How to use AemContextCallback

Interface AemContextCallback allows us to define some default operations which are common for all our test classes, e.g. to register our models.

Now, when we define JUnit rule for AemContext, we should create and pass our callback into AemContext‘s constructor.

After these changes, all our models in the defined package will be initialized. There is no need to do this explicitly anymore.

Mixing AemContextCallback and TestRule

So far, our callback does not make our life much easier, but we definitely can take more out of AemContextCallback! When you need to create some resource for a class under the test, you either build it directly in your test class (or some helper) or you load it from the file (e.g. json). We can easily move this logic into or callback implementing additionally JUnit’s TestRule interface. Let’s take a look at this:

So what is going on here? Method apply is called for each test in our test class. Here we just store this class to reuse later.

Then, when AemContext executes our callback, we build a path “/class_package/class_name.json”, load it with ContentLoader and set as a current resource.

Time for testing

Now it’s time to use it. Imagine, we have a simple model we want to test:

And also we prepared a json file with a resource to adapt to this model for test purposes. It’s located under “com.taradevko.aem.contcallback/SomeModelTest.json” in test resources section.

And now, finally – testing:

As before, we create AppContextSetup and pass it to the constructor of AemContext. But now it also got annotation @Rule.

Now, if we run the example, we can see that test passed successfully!

AemContextCallback test run example

Now, whenever we need to load resources from json, we just should put it on the correct path, and use our AppContextSetup. The rest will be done automatically!

What is next

You can do much more with AemContextCallback, like registering you stub implementations of OSGi services or executing additional callbacks on AemContext.

You can find the complete example in this repository.

Your thoughts are welcome