Posts

Unit Testing Hands on - For Sling Servlet

Image
This post is about creating Unit Test class for Sling Servlet, another commonly used Java class as part of an AEM application.  In Sling servlets, we have  SlingSafeMethodsServlet - read only servlet supporting GET  (doGet) SlingAllMethodsServlet - Supports POST, PUT and DELETE (doPost/doPut/doDelete) In either case, we have request and response objects using which desired code logic is written in Servlet.  For Unit testing, we have Mock sling request and sling response from Sling Mocks ( org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest  and org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse respectively) Writing unit test for Servlet involves the following Instantiate Servlet to be tested. Get mock request and response from AemContext Prepare the mock request object (per the code logic before calling doGet/doPost) Call doGet/doPost method of Servlet to be tested Assert the Servlet response (per the code logic) Inst...

Unit Testing Hands on - For WCMUsePojo

Image
This post illustrate the unit test for WCMUsePojo , Java class for backend logic as part of  AEM Component development. Quick Recap about WCMUsePojo :   WCMUsePojo initializes the objects associated with Bindings (Eg: WCMBindings/SlingBindings) via its init(Bindings) method which in turn calls activate() method for post initialization tasks. This init(Bindings bindings) method gets called if the POJO is instantiated in HTL via data-sly-use attribute. Bindings(javax.script.Bindings)  extends  Map(java.util.Map)  and hence it is basically a map object where  key  (type String) is the global variable and  value  is the respective object.  Once when the bindings are initialized, we are able to make use of the global variables which is available to us via methods like  getCurrentPage(), getProperties() etc. Example : When we call getCurrentPage() to get page object, below happens behind the scene  (considering the above flow) get...

Unit Testing in AEM - Hands on

Image
This post is about hands-on on Unit Testing Java class, part of an AEM application. We will be using AEM Mocks from  io.wcm.testing.mock.aem.junit5.*  and Mockito framework -  org.mockito.* (reason for using this is explained in previous post ) JUnit Version : JUnit 5 AEM Maven archetype : 22 IDE : Eclipse Testing related maven dependency : (available by default in AEM Maven archetype) JUnit5 (org.junit) AEM mocks (io.wcm.testing.aem-mock.junit5) Mockito framework (org.mockito) We mostly follow "Implementation first development" approach - Desired functionality is first coded and then test case is written for the same. For creating Test Java class,  Create Test Java Class Create AemContext Implement setUp method (creating test fixture, annotated with @BeforeEach ) Implement methods to be tested. (annotated with @Test ) Create Test Java Class: In Eclipse IDE, right click on the Java class to be tested ->  New -> Other -> JUnit -> JUnit Test case We ...

Unit testing in AEM - Introduction

Image
This post is about an introduction to Unit testing the Java class part of AEM application by starting with quick recap of JUnit framework followed by Mocking and APIs available specific to AEM with respect to testing.  Java class that we write as part of AEM involves Sling API/JCR API/AEM related APIs and it all ultimately targets the content on our repository.  In other words, the logic revolves around the content which in AEM context, is a Resource/Node and its related properties (may it be a Sling model/WCMUsePojo/Sling Servlets/OSGI component/any related for that matter)  Quick recap of basics: JUnit is the testing framework for Java and is available under the package - org.junit.* It provides Test Fixture, Test Runner and Test class Test fixture is fixed state of objects in which tests are run. One of the methods it includes which is relevant for us is setUp method that we write in Test class. (Annotated with @BeforeEach, JUnit5 / @Before, JUnit 4) Test class has m...

Apache Tika config in Lucene Index and Query Flow Summary

Image
This post is about the Apache tika config on Lucene full text Index and summary on queries/indexing that we discussed in past few posts. Apache Tika is used to detect and extract the text from varying file formats. It consist of Detector and Parser where Detector is used to detect the file format and Parser will parse the contents of the file.  In Lucene Index, Oak uses the default config which uses  TypeDetector -  org.apache.tika.detect.TypeDetector This detector uses the content type available in input metadata to arrive at the content type/mimeType DefaultParser -  org.apache.tika.parser.DefaultParser Composite parser which is based on all available specific parser implementations.  Eg. PDFParser, MP4Parser and all other parser implementation available in Apache Tika. Empty Parser -  org.apache.tika.parser.EmptyParser As with the name, it is a dummy parser/ not parses anything Hence defining mime types within Empty Parser is equivalent to excluding them...

Lucene Index in AEM - Part 3

Image
This post illustrates the use of analyzers in full text search with sample use case. Apache Lucene Analyzers : Analyzers as with the name is used to analyze the text both at the time of indexing and at the time of searching (via query execution) An analyzer examines the text of fields and generates a token stream. It can be either a  Single Java class or  Composed of a series of Tokenizer and Filter Java classes. Tokenizer breaks the data into lexical units or tokens Filters then examines these tokens -> amends/discard/create new one based on the configuration Series of Tokenizer + Filters => Analyzer There are direct Analyzer classes, Tokenizer and Filters available OOB. Based on our requirement we can choose to use either direc t Analyzer or Tokenizer + Filter combination.(Analyzer via composition) Examples: Analyzer -  StandardAnalyzer (org.apache.lucene.analysis.standard.StandardAnalyzer) Removes stop words, converts to lowercase, recognize URLs and emails - m...

Lucene Index in AEM - Part 2

Image
This post illustrates about full text search scenario and steps to create custom Lucene Full Text Index. On a high level, for full text search, we need to index all nodes and properties (these are the two major means in which our content is held in the repository)  For property: In order to make a specific property to be indexed for both full text and property constraint scenario, then in the property definition of respective indexRule , we need to add below property for Full text: Name Type Value nodeScopeIndex Boolean true For property constraint: (name and isRegexExp are interrelated as already explained in previous post) Name Type Value propertyIndex Boolean true name String propertyname or regex pattern isRegexExp Boolean false or true Example : jcr:title property of a page might be used in queries with property constraints or we might need to get the results of full text/contains queries based on the jcr:title  or both.  For node: indexRul...