Expand my Community achievements bar.

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

Junit post servlet session object giving null.

Avatar

Level 4

Hi ,

I am using the below code in post servlet .While debugging junit code getting null in session object .Can some one please help how to pass session to junit class.

 
Servlet code
String sourcePath = request.getParameter("Path");
String title = request.getParameter("title");
ResourceResolver resolver = request.getResourceResolver();
Session session = resolver.adaptTo(Session.class);
String assetDetails = createAssetNode(session, sourcePath,Title);
 
Junit code
 @Mock
    private MockSlingHttpServletRequest request;
    @Mock
    private MockSlingHttpServletResponse response;
    @Mock
    private ResourceResolver resourceResolver;
    @Mock
    private Session session;
 @BeforeEach
    void setUp() throws Exception {
    request = context.request();
    response = context.response();
    resourceResolver = context.request().getResourceResolver();
    context.registerAdapter(ResourceResolver.class, Session.class, session);
context.request().setQueryString("path=/content/dam/demo/sampleimage&title=sample");
}
void test_post() throws ServletException, IOException {  
 
demoservlet.doPost(request,response); 
        assertEquals("sample",response.getOutputAsString());
}
17 Replies

Avatar

Level 5

Hi @djohn98390536 ,

 

Instead of registering the session object as an adapter, try a when/then to return the object

 

 

lenient().when(resourceResolver.adaptTo(Session.class)).thenReturn(session)

 

 

 

Regards,

Anupam

Avatar

Level 4

Hi @anupampat tried the above code not working getting below error

 

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);
 
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.

Avatar

Community Advisor

How are you initializing your aemcontext ?

Avatar

Level 4

private final AemContext context = new AemContext(ResourceResolverType.RESOURCERESOLVER_MOCK);

Avatar

Community Advisor

Is it possible to share the complete code ? 
And also can you once try using ResourceResolverType.JCR_MOCK ?

Avatar

Level 4

@ExtendWith(AemContextExtension.class)
class CreatesampleServletTest {
private final AemContext context = new AemContext(ResourceResolverType.JCR_MOCK);
@InjectMocks
private CreatesampleServlet createsample = new CreatesampleServlet();
@Mock
private MockSlingHttpServletRequest request;
@Mock
private MockSlingHttpServletResponse response;
@Mock
private ResourceResolver resourceResolver;
@Mock
private Session session;
@BeforeEach
void setUp() throws Exception {
request = context.request();
response = context.response();
resourceResolver = context.request().getResourceResolver();
context.registerAdapter(ResourceResolver.class, Session.class, session);
context.request().setQueryString("path=/content/dam/demo/sampleimage&title=sample");
}
@test
void test_post() throws ServletException, IOException {

createsample.doPost(request,response);
assertEquals("sample",response.getOutputAsString());
}

Avatar

Level 4

can u share how it is working for you . i am still getting error.

Avatar

Community Advisor

SERVLET TEST class

 

package projectpackage;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;

import javax.jcr.Session;

import javax.servlet.ServletException;

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

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.jupiter.api.BeforeEach;

import org.junit.jupiter.api.Test;

import org.junit.jupiter.api.extension.ExtendWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import io.wcm.testing.mock.aem.junit5.AemContext;

import io.wcm.testing.mock.aem.junit5.AemContextExtension;

@ExtendWith(AemContextExtension.class)

class DemoServletTest {

private final AemContext context = new AemContext(ResourceResolverType.JCR_MOCK);

@InjectMocks

private DemoServlet demo = new DemoServlet();

@Mock

private MockSlingHttpServletRequest request;

@Mock

private MockSlingHttpServletResponse response;

@Mock

private ResourceResolver resourceResolver;

@Mock

private Session session;

@BeforeEach

void setUp() throws Exception {

request = context.request();

response = context.response();

resourceResolver = context.request().getResourceResolver();

context.registerAdapter(ResourceResolver.class, Session.class, session);

context.request().setQueryString("path=/content/dam/demo/sampleimage&title=sample");

}

@Test

void test_post() throws ServletException, IOException {

demo.doPost(request,response);

assertEquals("admin",response.getOutputAsString());

}

}

 

SERVLET

 

package projectpackage;

import java.io.IOException;

import javax.jcr.Session;

import javax.servlet.Servlet;

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

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

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

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

import org.osgi.framework.Constants;

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

@Component(service = Servlet.class, property = {Constants.SERVICE_DESCRIPTION + "=Demo Servlet", "sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.selectors=" + "selector1", "sling.servlet.resourceTypes=" + "project/components/demo", "sling.servlet.extensions=" + "json"})

public class DemoServlet extends SlingAllMethodsServlet {

@Override

protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {

String sourcePath = request.getParameter("Path");

String title = request.getParameter("title");

ResourceResolver resolver = request.getResourceResolver();

Session session = resolver.adaptTo(Session.class);

//String assetDetails = createAssetNode(session, sourcePath,Title);

response.getWriter().write(session.getUserID());

}

}

Avatar

Administrator

@djohn98390536 Did you find the suggestion helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!



Kautuk Sahni

Avatar

Level 4

No @kautuk_sahni  it is still not working for me .Still  i need more info on this.

Avatar

Community Advisor

Hi @djohn98390536 

Are you still getting session as a null or something else.

Above code which i shared is working fine.

MukeshYadav__0-1721761706095.png

can you share error if something else

@djohn98390536 Also I can see String sourcePath = request.getParameter("Path");

However in junit you are setting lowercase p

context.request().setQueryString("path=/content/dam/demo/sampleimage&title=sample");

Please correct it, else sourcePath will be null

 

package com.proeject.core.servlets;//change this package path according to your proeject structure

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import javax.jcr.Session;
import javax.servlet.ServletException;
import org.apache.sling.api.resource.ResourceResolver;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;

@ExtendWith(AemContextExtension.class)
class DemoServletTest {
	private final AemContext context = new AemContext(ResourceResolverType.JCR_MOCK);
	@InjectMocks
	private DemoServlet demo = new DemoServlet();
	@Mock
	private MockSlingHttpServletRequest request;
	@Mock
	private MockSlingHttpServletResponse response;
	@Mock
	private ResourceResolver resourceResolver;
	@Mock
	private Session session;

	@BeforeEach
	void setUp() throws Exception {
		request = context.request();
		response = context.response();
		resourceResolver = context.request().getResourceResolver();
		context.registerAdapter(ResourceResolver.class, Session.class, session);
		context.request().setQueryString("path=/content/dam/demo/sampleimage&title=sample");
	}
	@Test
	void test_post() throws ServletException, IOException {
	demo.doPost(request,response);
	assertEquals("admin/content/dam/demo/sampleimage",response.getOutputAsString());
	
	}

}

 

 

 

package com.project.core.servlets;//change this as per your project structure

import java.io.IOException;
import javax.jcr.Session;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;

@Component(service = Servlet.class, property = {Constants.SERVICE_DESCRIPTION + "=Demo Servlet", "sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.selectors=" + "selector1", "sling.servlet.resourceTypes=" + "project/components/demo", "sling.servlet.extensions=" + "json"})
public class DemoServlet extends SlingAllMethodsServlet {	
	@Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
		String sourcePath = request.getParameter("path");
		String title = request.getParameter("title");
		ResourceResolver resolver = request.getResourceResolver();
		Session session = resolver.adaptTo(Session.class);
		//String assetDetails = createAssetNode(session, sourcePath,Title);
		response.getWriter().write(session.getUserID()+sourcePath);
	}
}

 

Thanks 

Avatar

Level 4

yes in my case i m using the session in a method there i am still getting session as null

String assetDetails = createAssetNode(session, sourcePath,Title);

 

Avatar

Community Advisor

Could you please confirm if yours Servlet is registered by path or resourceType?

Avatar

Community Advisor

Anyway it is working for register by path as well I checked just now

Thanks

Avatar

Community Advisor

Hi

First thing you can copy past above servlet and test class it should pass in you system

If above code pass check following points in your servlet:-

  1. ResourceResolverType.JCR_MOCK
  2. Typo in Path in test class
  3. compare imports statements

Thanks