session object in unit test | Community
Skip to main content
sreenu539
Level 7
March 21, 2023

session object in unit test

  • March 21, 2023
  • 3 replies
  • 3718 views

I am trying to write test cases for below existing code.  Test a node exists, if node exists get a node property and return. Nodes and properties will be created with AemContext.

 

 

 

Session session = resourceResolver.adaptTo(Session.class); Node mfDataNode = null; if(session.nodeExists(jcrPath+ "/" + dataPath)) { mfDataNode = session.getNode(jcrPath+ "/" + dataPath); jsonData = mfDataNode.getProperty("reform-data").getString(); }

 

 

 

I tried below test code but session returned is mock session instance and session.nodeExists always comes false.

Any help , how to test above piece of code.

Below is source code, unit test code written so far.

 

Here is the complete servlet source code:

 

 

( service = Servlet.class, name = "Reform Servlet", property = { "sling.servlet.paths=" + "/bin/reform-message", "sling.servlet.methods=" + HttpConstants.METHOD_GET } ) public class ReformServlet extends SlingAllMethodsServlet implements Serializable { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(ReformServlet.class); private ConfigurationAdmin configAdmin; private ResourceResolverFactory resolverFactory; protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException,IOException { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); try { log.info("ReformServlet.doGet"); out.write( getMessage()); } catch (Exception ex) { { response.setStatus(500); out.write("doGet - ReformServlet"); } } } private String getMessage() { //servlet returns JSON string String jsonData = null; ResourceResolver resourceResolver = null; try { String jcrPath = getProperty("/cotent/test"); String dataPath = getProperty("reform-cache"); java.util.Map<String, Object> param = new java.util.HashMap<String, Object>(); param.put(ResourceResolverFactory.USER, Constants.ConfigProperties.ISG_SYSTEM_USER); resourceResolver = resolverFactory.getServiceResourceResolver(param); Session session = resourceResolver.adaptTo(Session.class); Node mfDataNode = null; if(session.nodeExists(jcrPath + "/" + dataPath)) { mfDataNode = session.getNode(jcrPath+ "/" + dataPath); jsonData = mfDataNode.getProperty("reform-data").getString(); } else { log.error("data DOES NOT exist"); } } catch (Exception e) { log.error("data - caught exception", e); } finally { try { resourceResolver.close(); } catch(Throwable t) {} } return jsonData; } protected String getProperty(String key) throws Exception { String property = null; try { Configuration config = (Configuration) configAdmin .getConfiguration(Constants.ConfigProperties.OSGI_CONFIG_NAME); Dictionary props = config.getProperties(); property = (String)props.get(key); } catch(Exception e) { log.error("getProperty - caught exception getting property {}", key); throw(e); } return property; } }

 

 

 

 

Here is the test class written so far:

 

 

@ExtendWith({ AemContextExtension.class, MockitoExtension.class }) class ReformServletTest { @InjectMocks private ReformServlet fixture = new ReformServlet(); @Mock private ConfigurationAdmin configAdmin; @Mock private ResourceResolverFactory resolverFactory; @BeforeEach void setUp(AemContext context) throws IOException { MockitoAnnotations.initMocks(this); context.create().resource("/content/test", ImmutableMap.<String, Object>builder() .put("jcr:title", "test page") .build()); context.create().resource("/content/test/reform-cache", ImmutableMap.<String, Object>builder() .put("jcr:title", "reform cache") .build()); context.registerService(ConfigurationAdmin.class, configAdmin); context.registerService(ResourceResolverFactory.class, resolverFactory); ConfigurationAdmin configAdmin = context.getService(ConfigurationAdmin.class); } void doGet(AemContext context) throws ServletException, IOException, LoginException { context.currentResource("/content/test"); MockSlingHttpServletRequest request = context.request(); MockSlingHttpServletResponse response = context.response(); Configuration configurationMock = Mockito.mock(Configuration.class); Mockito.when(configAdmin.getConfiguration(Mockito.anyString())).thenReturn(configurationMock); Mockito.when(configurationMock.getProperties()).thenReturn(new Hashtable<String, Object>(){{ put("jcrPath", "/content/test"); put("dataPath", "reform-cache"); }}); Mockito.when(resolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(context.resourceResolver()); Session mockSession = Mockito.mock(Session.class); context.registerAdapter(ResourceResolver.class, Session.class, mockSession); fixture.doGet(request, response); } }

 

 

UPDATE:

I have update unit test code to use JCR_MOCK resource resolver type.

Getting error 

java.lang.IllegalStateException: Resource resolver is already closed.

at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.checkClosed(ResourceResolverImpl.java:186)
at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.adaptTo(ResourceResolverImpl.java:807)
at org.apache.sling.testing.mock.sling.context.SlingContextImpl.tearDown(SlingContextImpl.java:225)
at io.wcm.testing.mock.aem.context.AemContextImpl.tearDown(AemContextImpl.java:105)

@ExtendWith({ AemContextExtension.class, MockitoExtension.class }) class ReformServletTest { private final AemContext context = new AemContext(ResourceResolverType.JCR_MOCK); @InjectMocks private MoneyMarketReformServlet fixture = new MoneyMarketReformServlet(); @Mock private ConfigurationAdmin configAdmin; @Mock private ResourceResolverFactory resolverFactory; @Mock private ResourceResolver leakedResourceResolver; @BeforeEach void setUp() throws IOException { MockitoAnnotations.initMocks(this); context.create().resource("/content/test", ImmutableMap.<String, Object>builder() .put("jcr:title", "test page") .build()); context.create().resource("/content/test/reform-cache", ImmutableMap.<String, Object>builder() .put("jcr:title", "reform cache") .put("messageData", "{\"globalMessage\":\"some message\"}") .build()); // context.registerService(ConfigurationAdmin.class, configAdmin); // context.registerService(ResourceResolverFactory.class, resolverFactory); } @2785667 void doGet() throws ServletException, IOException, LoginException { context.currentResource("/content/test"); MockSlingHttpServletRequest request = context.request(); MockSlingHttpServletResponse response = context.response(); Configuration configurationMock = Mockito.mock(Configuration.class); Mockito.when(configAdmin.getConfiguration(Mockito.anyString())).thenReturn(configurationMock); Mockito.when(configurationMock.getProperties()).thenReturn(new Hashtable<String, Object>(){{ put("jcrPath", "/content/test"); put("dataPath", "reform-cache"); }}); Mockito.when(resolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(Mockito.spy(context.resourceResolver())); // Session mockSession = Mockito.mock(Session.class); // context.registerAdapter(ResourceResolver.class, Session.class, mockSession); fixture.doGet(request, response); assertEquals(response.getOutputAsString(), "{\"globalMessage\":\"some message\"}"); } }

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

3 replies

sreenu539
sreenu539Author
Level 7
March 21, 2023

Made couple of changes :

//USING JCR_MOCK resource resolver type
private final AemContext context = new AemContext(ResourceResolverType.JCR_MOCK);

 

and

Mockito.when(resolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(Mockito.spy(context.resourceResolver()));

 

below is latest unit test code, this is almost working, and throwing "resource resolver is already closed" by AemContext 

 

java.lang.IllegalStateException: Resource resolver is already closed. at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.checkClosed(ResourceResolverImpl.java:186) at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.adaptTo(ResourceResolverImpl.java:807) at org.apache.sling.testing.mock.sling.context.SlingContextImpl.tearDown(SlingContextImpl.java:225) at io.wcm.testing.mock.aem.context.AemContextImpl.tearDown(AemContextImpl.java:105) at io.wcm.testing.mock.aem.junit5.AemContext.tearDownContext(AemContext.java:107) at io.wcm.testing.mock.aem.junit5.AemContextExtension.lambda$afterEach$3(AemContextExtension.java:152) at io.wcm.testing.mock.aem.junit5.AemContextExtension.applyAemContext(AemContextExtension.java:180) at io.wcm.testing.mock.aem.junit5.AemContextExtension.afterEach(AemContextExtension.java:147) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$12(TestMethodTestDescriptor.java:233) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$14(TestMethodTestDescriptor.java:245) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:243) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:232) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:133) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229) at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197) at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

 

//code thatis doing resolver close in servlet

finally
{
try { resourceResolver.close(); } catch(Throwable t) {}
}

 

 

 

@ExtendWith({ AemContextExtension.class, MockitoExtension.class }) class MoneyMarketReformServletTest { //USING JCR_MOCK resource resolver type private final AemContext context = new AemContext(ResourceResolverType.JCR_MOCK); @InjectMocks private ReformServlet fixture = new ReformServlet(); @Mock private ConfigurationAdmin configAdmin; @Mock private ResourceResolverFactory resolverFactory; @BeforeEach void setUp() throws IOException { MockitoAnnotations.initMocks(this); context.create().resource("/content/test", ImmutableMap.<String, Object>builder() .put("jcr:title", "test page") .build()); context.create().resource("/content/test/reform-cache", ImmutableMap.<String, Object>builder() .put("jcr:title", "reform cache") .put("mmrMessageData", "{\"globalMessage\":\"some message\"}") .build()); // context.registerService(ConfigurationAdmin.class, configAdmin); // context.registerService(ResourceResolverFactory.class, resolverFactory); } void doGet() throws ServletException, IOException, LoginException { context.currentResource("/content/test"); MockSlingHttpServletRequest request = context.request(); MockSlingHttpServletResponse response = context.response(); Configuration configurationMock = Mockito.mock(Configuration.class); Mockito.when(configAdmin.getConfiguration(Mockito.anyString())).thenReturn(configurationMock); Mockito.when(configurationMock.getProperties()).thenReturn(new Hashtable<String, Object>(){{ put("jcrPath", "/content/test"); put("dataPath", "reform-cache"); }}); Mockito.when(resolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(Mockito.spy(context.resourceResolver())); // Session mockSession = Mockito.mock(Session.class); // context.registerAdapter(ResourceResolver.class, Session.class, mockSession); fixture.doGet(request, response); assertEquals(response.getOutputAsString(), "{\"globalMessage\":\"some message\"}"); } }

 

 

 

Shivam153
Level 3
March 21, 2023

Hi @sreenu539 ,

 

Can you try to mock Session object like 

@Mock
Session session;

and use lenient when try to return object like:

lenient().when().then(session.nodeExits("path"))Return(true);

It worked for me.

sreenu539
sreenu539Author
Level 7
March 21, 2023

I already stubbed content using context.create() , why I could not just have resource resolver read context content and not get this exception.

sreenu539
sreenu539Author
Level 7
March 21, 2023

I just need to write unit test for some thing like this. Even this kind of style code is failing with Resourceresolver is alredy closed exception. 

 

try (ResourceResolver resolver = factory.getServiceResourceResolver(authInfo)) { Resource resource = resolver.getResource("/content/sourcedcode/jcr:content"); if (Objects.nonNull(resource)) { //read resource data } } catch (Exception e) { e.printStackTrace(); }

 

April 9, 2024

Instead of ResourceResolverType.JCR_MOCK you could try using:

AemContext context = new AemContext(ResourceResolverType.JCR_OAK);

This type of AemContext should pretty much work as if there was actual JCR, in fact if I recall correctly, it creates a JCR tree in-memory. I believe it could be working on an actual Session instance, not a MockSession.

guruprasadg2455
Level 2
August 19, 2024

@sreenu539 you can pass cloned resource resolver 

aemContext.resourceResolver().clone(null)