Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

how to do servlet unit testing

Avatar

Level 3

hi guys i need help from you, i created chillist servlet for reading properties from /content it returns a JSONArray of the node's child node paths and properties.

so plz help for unit testing. i need unit testing script for this code, this my code

package com.aem.community.core.servlets;

import java.io.IOException;

import javax.jcr.Node;

import javax.jcr.NodeIterator;

import javax.jcr.RepositoryException;

import javax.servlet.ServletException;

import org.apache.felix.scr.annotations.Service;

import org.apache.felix.scr.annotations.sling.SlingServlet;

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import org.apache.sling.commons.json.JSONArray;

import org.apache.sling.commons.json.JSONException;

import org.apache.sling.commons.json.JSONObject;

import org.apache.sling.commons.json.jcr.JsonJcrNode;

import org.osgi.service.component.annotations.Component;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

@Component(enabled = true, immediate = true)

@Service(ChildList.class)

@SlingServlet(resourceTypes="sling/servlet/default",selectors="childlist",methods="GET",extensions="json",metatype=true)

public class ChildList extends SlingAllMethodsServlet {

protected final Logger loger = LoggerFactory.getLogger(ChildList.class);

private static final long serialVersionUID = 9176255033916949528L;

private JSONArray array;

@Override

public void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)

throws ServletException, IOException {

try{

ResourceResolver resolver = request.getResourceResolver();

Resource resource = resolver.getResource(request.getRequestPathInfo().getResourcePath());

Node node = null;

if (resource != null) {

node = resource.adaptTo(Node.class);

}

if (node == null){

throw new RepositoryException();

}

NodeIterator it = node.getNodes();

array = new JSONArray();

while (it.hasNext()) {

Node child = it.nextNode();

if (loger.isDebugEnabled()){

loger.debug("resource......."+child.getPath());

}

JSONObject obj = new JsonJcrNode(child);

array.put(obj);

response.setContentType("application/json");

response.getOutputStream().print(array.toString());

}

}

catch(RepositoryException e) {

throw new ServletException("404 HTTP ERROR Page Not Found", e);

}

catch(JSONException e)

{

loger.error("Could not formulate JSON response");

throw new ServletException("Error", e);

}

}

}

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Today I rewrote unittests for the whole day ... so while I just was on it, I wrote them for this question, too.

You can find the complete code at https://github.com/joerghoh/cqdump/tree/master/unittests

Clone it and then run it (the usual "mvn clean install").

The relevant bits and pieces:

I used the AEM Mocks from wcm.io, which work pretty good for usecases like yours.

HTH,

Jörg

View solution in original post

50 Replies

Avatar

Employee Advisor

I am sorry, it's really hard to help here without having access to the complete code.

I just retested my code at the mentioned github URL and it compiles ; maybe you can start there and try if it compiles on your system as well. As your initial request I provided you a sample how a unittest can look like.

And then as a second step you can try to transfer the settings to your environment/code.

Jörg

Avatar

Level 3

how to  servlet can be disabled by the bundle configuration: enable.childlist.filter {Boolean}

??????.

Avatar

Employee Advisor

Sorry, I don't understand your question. What do you want to achieve?

Jörg

Avatar

Level 3

hi Jörg Hoh​ , still didnt get any solution.., http://localhost:4502/content.childlist.json am passing this url ,that time our childlist servlet is invoked, and am getting  response jsonarray properties of under /content  childnodes ..now i need unittesting for servlet.,

so  please write atleast one testcase code and send me..plzzzz... this my jsonarray response. Capture.PNG

this is my servlet code

import java.io.IOException;

import javax.jcr.Node;

import javax.jcr.NodeIterator;

import javax.jcr.RepositoryException;

import javax.servlet.ServletException;

import org.apache.felix.scr.annotations.Service;

import org.apache.felix.scr.annotations.sling.SlingServlet;

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import org.apache.sling.commons.json.JSONArray;

import org.apache.sling.commons.json.JSONException;

import org.apache.sling.commons.json.JSONObject;

import org.apache.sling.commons.json.jcr.JsonJcrNode;

import org.osgi.service.component.annotations.Component;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

@Component(enabled = true, immediate = true)

@Service(ChildList.class)

@SlingServlet(resourceTypes="sling/servlet/default",selectors="childlist",methods="GET",ex tensions="json",metatype=true)

public class ChildList extends SlingAllMethodsServlet {

protected final Logger loger = LoggerFactory.getLogger(ChildList.class);

private static final long serialVersionUID = 9176255033916949528L;

private JSONArray array;

@Override

public void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)

throws ServletException, IOException {

try{

ResourceResolver resolver = request.getResourceResolver();

Resource resource = resolver.getResource(request.getRequestPathInfo().getResourcePath());

Node node = null;

if (resource != null) {

node = resource.adaptTo(Node.class);

}

if (node == null){

throw new RepositoryException();

}

NodeIterator it = node.getNodes();

array = new JSONArray();

while (it.hasNext()) {

Node child = it.nextNode();

if (loger.isDebugEnabled()){

loger.debug("resource......."+child.getPath());

}

JSONObject obj = new JsonJcrNode(child);

array.put(obj);

response.setContentType("application/json");

response.getOutputStream().print(array.toString());

}

}

catch(RepositoryException e) {

throw new ServletException("404 HTTP ERROR Page Not Found", e);

}

catch(JSONException e)

{

loger.error("Could not formulate JSON response");

throw new ServletException("Error", e);

}

}

}

Avatar

Level 10

Have you invoked the servlet in a test and run an assert?

Avatar

Level 3

actually this is first time for unittesting.. i dnt know, how to invoke servlet in test class and  from test class how to send req and get response..,

Avatar

Level 3

and am referred documentation also i didn't get anything..

Avatar

Level 10

WHen you create a Maven 12 Archetype:

Creating an Adobe Experience Manager 6.3 Project using Adobe Maven Archetype 12

Notice the Java classes under Test package. You can write a test from the default test classes to call your servlet using HTTP APIS and do an assert on the return values. I would start with that.

If you do not know how to call a servlet using HTTP APIS - look here - Adobe Experience Manager Help | Invoking Adobe Experience Manager Sling Servlets using Apache HTTP A...

Avatar

Level 3

that is i know where am write test class..,in test class i written using httpclient get status code , with that status code i done test case,,but i want using mock objects check those test cases

public class HttpClientReq

{

private static final String PROTOCOL = "http";

    private static final int PORT = 4502;

    private static final String HOST = "localhost";

    private static final String COOKIE_NAME = "login-token";

    private static  GetMethod get;

    private static String username = "admin";

    private static String password = "admin";

    private static int status;

public static GetMethod getGet() {

return get;

}

public static int getStatus() {

return status;

}

public static void setStatus(int status) {

HttpClientReq.status = status;

}

public static void setGet(GetMethod get) {

HttpClientReq.get = get;

}

public static void authenticateMethod() throws HttpException, IOException

{

     ChildListTest list=new ChildListTest();

HttpClient client = new HttpClient();

        String token = getStatus(username, password, client);

        if (token == null) {

            System.err.println("No login cookie set.");

            return;

        }

       // System.out.println("token = " + token);

         get = new GetMethod(String.format("%s://%s:%s%s", PROTOCOL, HOST, PORT,list.getPath()));

        get.addRequestHeader("Cookie", String.format("%s=%s", COOKIE_NAME, token));

        int status = client.executeMethod(get);

        if (status == 200) {

            //System.out.println("response="+get.getResponseBodyAsString());

        } else {

            System.err

            .println("Unexcepted response code " + status + "; msg: " + get.getResponseBodyAsString());

        }

}

private static String getStatus(String username, String password, HttpClient client) throws IOException,

     HttpException {

String token = null;

PostMethod authRequest = new PostMethod(String.format("%s://%s:%s/j_security_check", PROTOCOL, HOST, PORT));

authRequest.setParameter("j_username", username);

authRequest.setParameter("j_password", password);

authRequest.setParameter("j_validate", "true");

  status = client.executeMethod(authRequest);

if (status == 200) {

     Header[] headers = authRequest.getResponseHeaders("Set-Cookie");

     for (Header header : headers) {

         String value = header.getValue();

        // System.out.println("valueee="+value);

         if (value.startsWith(COOKIE_NAME + "=")) {

             int endIdx = value.indexOf(';');

             if (endIdx > 0) {

                 token = value.substring(COOKIE_NAME.length() + 1, endIdx);

             }

         }

     }

}

else {

     System.err

             .println("Unexcepted response code " + status + "; msg: " + authRequest.getResponseBodyAsString());

}

return token;

}

}

Avatar

Level 3

this is my test class ...i written 2 test cases with help of Httpclientreq class

public class ChildListTest

{

private static String path;

public String getPath() {

return path;

}

@SuppressWarnings({ "static-access" })

@Test

public void urlTest() throws HttpException, IOException 

{

path="/apps.childlist.json";

HttpClientReq main=new HttpClientReq();

main.authenticateMethod();

assertEquals(200,main.getStatus()); 

}

@SuppressWarnings("static-access")

@Test

public void urlTest2() throws HttpException, IOException

{

path="/content.childlist.json";

HttpClientReq main=new HttpClientReq();

main.authenticateMethod();

assertEquals(200,main.getStatus()); 

}

}

Avatar

Level 10

Joerg has pointed you to a lot of code that uses MOCK APIs.

Avatar

Level 3

in that while am executing junit test class am getting so many errors occured..

Avatar

Level 3

that's why am asking you guys execute our code in ur local write unit test for it...plz guys dnt mind..,

am requesting...

Avatar

Level 10

Did you take Joergs example and execute it - I built his example and it works

JoergCode.png

Let us know if you executed this and inspected in detail the Java app logic here.

Avatar

Level 3

org.apache.sling.api.servlets,version=[2.2,3) -- Cannot be resolved

org.apache.sling.api.resource,version=[2.10,3) -- Cannot be resolved

Avatar

Level 10

Did you fork this repo and download it -- cqdump/unittests at master · joerghoh/cqdump · GitHub

It builds as i showed the build results. I also deployed it successfully.

JoergBundle.png

WHat version of AEM are you using?

Avatar

Level 10

You will have to modify the dependencies to work with AEM 6.2. Try rebuilding this code with AEM Maven 10 archetype and UBER 6.2 JAR file.