Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

How write unit test case for sling servlet which have sql query code

coder786
Level 1
Level 1

Hi, 

How I can write unit test case for sling servlet which have sql query code. I have tried to write unit test but that is not working kindly look below is the sling servlet code and unit test code share what's wrong I am doing

# Servlet


import java.io.IOException;
import java.util.Iterator;
import java.util.Objects;

import javax.servlet.Servlet;

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.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.wcm.api.Page;

@component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "= Global Search Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET, "sling.servlet.paths=" + "/bin/mysite/globalsearch" })
public class GlobalSearchServlet extends SlingAllMethodsServlet {

private static final long serialVersionUID = 1L;
private static final transient Logger LOG = LoggerFactory.getLogger(GlobalSearchServlet.class);

@Override
public void doGet(SlingHttpServletRequest req, SlingHttpServletResponse res) {
ResourceResolver resourceResolver = req.getResourceResolver();
String keyword = null;
res.setContentType("application/json");
res.setCharacterEncoding("UTF-8");
JSONArray jsonArray = new JSONArray();
try {
keyword = req.getParameter("q");
if (Objects.nonNull(keyword)) {
String query = "select * from [cq:Page] as a where contains(*, '"+keyword+"') and isdescendantnode(a, '/content/mysite')";
Iterator<Resource> results = resourceResolver.findResources(query, "sql");
while (results.hasNext()) {
JSONObject object = new JSONObject();
Resource resource = results.next();
Page page =resource.adaptTo(Page.class);
object.put("path", page.getPath());
object.put("title", page.getTitle());
jsonArray.put(object);
}
} else {
LOG.info("Query Parameter is missing in request.");
}
res.getWriter().print(jsonArray);
} catch (IOException | JSONException ioe) {
LOG.error("Error occurred. Error ", ioe);
}
}
}

 

 

#Unit Test

 


import static org.junit.Assert.assertEquals;
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.wcm.testing.mock.aem.junit.AemContext;

public class GlobalSearchServletTest {

private static final String MOCK_JSON = "/globalsearch/globalsearch.json";

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

static final Logger LOG = LoggerFactory.getLogger(GlobalSearchServletTest.class);


@Before
public void setup() {
context.load().json(MOCK_JSON, "/content");
}


@test
public void testDoGet() throws ServletException, IOException, JSONException {
GlobalSearchServlet servlet = new GlobalSearchServlet();

context.currentPage(context.pageManager().getPage("/content/mysite"));
context.currentResource(context.resourceResolver().getResource("/content/mysite"));
context.requestPathInfo().setResourcePath("/content/mysite");

MockSlingHttpServletRequest request = context.request();
request.setQueryString("q=the");

MockSlingHttpServletResponse reponse = context.response();

servlet.doGet(request, reponse);

System.out.println("RESPONSE=="+context.response().getOutputAsString());


LOG.info("output = {}", context.response().getOutputAsString());
assertEquals("[{\"message\":\"0 results found\",\"status\":false}]",context.response().getOutputAsString());
}

}

9 Replies
Jörg_Hoh
Employee
Employee

Can you share details what's not working? Do you get an exception? Is the testcase failing on an assert?

coder786
Level 1
Level 1

I am not getting any exception But while running the unit test case I am not getting any response or to be more precise not getting any result from query execution

String query = "select * from [cq:Page] as a where contains(*, '"+keyword+"') and isdescendantnode(a, '/content/mysite')";
Iterator<Resource> results = resourceResolver.findResources(query, "sql");

 

Below is the page json. Can you share what's wrong I am doing here or it not possible? 

 

{
"jcr:content": "nt:unstructured",
"mysite": {
"jcr:primaryType": "cq:Page",
"jcr:content": {
"jcr:primaryType": "cq:PageContent",
"jcr:title": "the mysite page"
},
"dashboard": {
"jcr:primaryType": "cq:Page",
"jcr:content": {
"jcr:primaryType": "cq:PageContent",
"jcr:title": "the dashboard page"
},
"homepage": {
"jcr:primaryType": "cq:Page",
"jcr:content": {
"jcr:primaryType": "cq:PageContent",
"jcr:title": "the home page"
},
"userpage": {
"jcr:primaryType": "cq:Page",
"jcr:content": {
"jcr:primaryType": "cq:PageContent",
"jcr:title": "the user page"
}
},
"productpage": {
"jcr:primaryType": "cq:Page",
"jcr:content": {
"jcr:primaryType": "cq:PageContent",
"jcr:title": "the product page"
}
}
}
}
}
}

 

Jörg_Hoh
Employee
Employee
Both the testcase and the test data look reasonable, and i don't understand what could be wrong here. Can you execute that testcase in an IDE, set a breakpoint and inspect in the debugger the loaded repository structure?
coder786
Level 1
Level 1
Can you advice where i can put logger to check what the content repository loaded?
Jörg_Hoh
Employee
Employee
In eclipse when I set a breakpoint in the testcase and I can drill down into all available objects in the current scope, and if you are going down in the AemContext object you can find the content of the repo. A bit cumbersome, but works. I am not aware of any convenience method to dump the content of the repository of the AemContext.
Kamal_Kishor
Level 2
Level 2

I have the same issue -

while I can see the resource created with context.load().json(inputStream, "/content");

 

Issue is when executing Iterator<Resource> resources = resolver.findResources(query, "JCR-SQL2")
I am not getting the resource in iterator.

@Jörg_Hoh

zaddm
Level 1
Level 1

@Kamal_Kishor were you able to resolve this? I am facing similar issue.

johnv30691242
Level 1
Level 1

I've found that when using JCR_OAK and the findResources() method, it works once you've committed the loaded data from the JSON:

@Before
public void setup() {
    context.load().json(MOCK_JSON, "/content");
    context.resourceResolver().commit();
}