session object in unit test
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\"}");
}
}