Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events

TestCase for getChildnodes

Avatar

Level 3

Dear All,

 

I have written one getchildnodesIMPL service class for which trying to write JUNIT and written the below JUNIT. But in my code coverage it is not taking.

 

*************** JAVA Class ****************

private void extracted(ResourceResolver resourceResolver, Node rootNode, JsonObject jsonObject) throws RepositoryException {
NodeIterator childNodeIterator = rootNode.getNodes();
JsonArray jsonArray = new JsonArray();
while (childNodeIterator.hasNext()) {
Node childNode = childNodeIterator.nextNode();
JsonObject jsonObjectChild = getJsonObject(resourceResolver, childNode);
if (jsonObjectChild == null) continue;
if (hasNodesAsPageOrFolder(childNode)) extracted(resourceResolver, childNode, jsonObjectChild);
jsonArray.add(jsonObjectChild);
}
if (jsonArray.size() != 0) jsonObject.add("childNodes", jsonArray);
}

 

****************** My JUNIT *********************

private ResourceResolverFactory resolverFactory = mock(ResourceResolverFactory.class);
 
private ResourceResolver resourceResolver = mock(ResourceResolver.class);
 
private Resource resource = mock(Resource.class);
 
private Node node = mock(Node.class);
 
private NodeIterator nodeIterator = mock(NodeIterator.class);
 

@BeforeEach
void setUp() throws RepositoryException {

when(resource.adaptTo(Node.class)).thenReturn(node);
when(node.hasNode(Mockito.anyString())).thenReturn(true);
when(node.getNode(Mockito.anyString())).thenReturn(node);
when(node.getNodes()).thenReturn(nodeIterator);
when(nodeIterator.hasNext()).thenReturn(true, false);
when(nodeIterator.nextNode()).thenReturn(node);
}

 

Can anyone please let me know what I am doing wrong here.

 

Thanks

Snaik

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

2 Replies

Avatar

Community Advisor

@subnaik 

It looks like you are trying to test a method named `extracted` that operates on a `Node` hierarchy. It seems that you are mocking the relevant classes and methods, but there are a few things that might need improvement:

1. Mocking the `ResourceResolverFactory` and `ResourceResolver` classes:
Ensure that you mock the behavior of the `ResourceResolverFactory` to return the `b`. Make sure that the mocked `ResourceResolver` is being used correctly in your actual method.

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

2. Setting up the `NodeIterator` to return a sequence of nodes:
Make sure the `NodeIterator` is properly set up to return a sequence of nodes when `getNodes()` is called.

when(nodeIterator.hasNext()).thenReturn(true, true, false);
when(nodeIterator.nextNode()).thenReturn(childNode1, childNode2);

You may need to create separate mock objects for each node in your hierarchy.

3. Verify the method calls:
After invoking your method, you can use Mockito's `verify` to ensure that the expected methods on your mocks were called.

verify(node, times(2)).getNodes(); // or any other expected method calls

4. Check code coverage settings:
Ensure that your code coverage settings are correctly configured to include your test classes and that the relevant code paths are being executed during your tests.

 

Hope this helps.

Avatar

Level 3

Thanks Diksha,

 

Here my scenario is that I am hitting one Servlet (http://localhost:4502/bin/content/api/getChildNodes?type=grb&uuid=078b036a-d536-5b8e-9893-94c92041f4...)  and this servlet is calling the below GetChildNodesServiceImpl class and the code is below.

 

************************************* JAVA ***********************************

@Component(service = GetChildNodesAPIService.class)
public class GetChildNodesAPIServiceImpl implements GetChildNodesAPIService {
 
@Reference
transient ResourceResolverFactory resolverFactory;
    
private transient Map<String, Object> param = new HashMap<>();
    
    private static final Logger LOGGER = LoggerFactory.getLogger(GetChildNodesAPIServiceImpl.class);
    
    public GetChildNodesAPIServiceImpl() {
param.put(ResourceResolverFactory.SUBSERVICE, Constants.DATAWRITE_SERVICE);
}
    
    private ResourceResolver getResourceResolver() throws LoginException {
return resolverFactory.getServiceResourceResolver(param);
}
 
    @Override
    public ServletResponse<String> getChildNodesResponse(SlingHttpServletRequest request, String type, String uuid) {

String contentPath;
try (ResourceResolver resourceResolver = getResourceResolver()) {
Session session = resourceResolver.adaptTo(Session.class);
//session ==== com.adobe.granite.repository.impl.CRX3SessionImpl@558dee61 uuid ==== 078b036a-d536-5b8e-9893-94c92041f4d3 type ==== grb
LOGGER.info("session GetChildNodesAPIServiceImpl ===== "+session + " uuid GetChildNodesAPIServiceImpl ====== "+uuid +" type GetChildNodesAPIServiceImpl ==== "+ type);
contentPath = ApiUtility.getResourcePathForPage(type, uuid, session);
LOGGER.info("contentPath GetChildNodesAPIServiceImpl ===== "+contentPath);
//contentPath GetChildNodesAPIServiceImpl ===== /content/country/test/grb/automobile
Node rootNode = session.getNode(contentPath);
LOGGER.info("rootNode GetChildNodesAPIServiceImpl ===== "+rootNode);
//rootNode GetChildNodesAPIServiceImpl ===== Node[NodeDelegate{tree=/content/country/test/grb/automobile:
JsonObject jsonObject = new JsonObject();
extracted(resourceResolver, rootNode, jsonObject);
return validateEmptyJsonResponse(uuid, jsonObject);
} catch (Exception e) {
LOGGER.error(String.format(Constants.THERE_WAS_AN_ERROR + Constants.CURLY_BRACKETS, e));
return new ServletResponse<>(ServletResponse.ServletResponseType.RES_400, e.getMessage());
}
}

/**
* extract all child node properties as json
*
* @Param resourceResolver
* @Param rootNode
* @Param jsonObject
* @Return response
*/
private void extracted(ResourceResolver resourceResolver, Node rootNode, JsonObject jsonObject) throws RepositoryException {
NodeIterator childNodeIterator = rootNode.getNodes();
JsonArray jsonArray = new JsonArray();
while (childNodeIterator.hasNext()) {
Node childNode = childNodeIterator.nextNode();
LOGGER.info("childNode GetChildNodesAPIServiceImpl ===== "+childNode);
//===== Node[NodeDelegate{tree=/content/country/test/grb/automobile/Vendors: { jcr:primaryType = cq:Page, jcr:createdBy = admin, jcr:created = 2023-08-17T12:22:50.609+05:30, jcr:content = { ... }, honda0 = { ... }, automobile = { ... }, honda015 = { ... }, honda016 = { ... }, ...}}]
// childNode GetChildNodesAPIServiceImpl ===== Node[NodeDelegate{tree=/content/country/test/grb/automobile/Vendors/
// childNode GetChildNodesAPIServiceImpl ===== Node[NodeDelegate{tree=/content/country/test/grb/automobile/Vendors/honda0: { jcr:primaryType = cq:Page, }
JsonObject jsonObjectChild = getJsonObject(resourceResolver, childNode);
LOGGER.info("jsonObjectChild GetChildNodesAPIServiceImpl ===== "+jsonObjectChild);
//jsonObjectChild GetChildNodesAPIServiceImpl ===== {"pageName":"Vendors","pageTitle":"Vendors","pagePath":"/content/country/test/grb/automobile/Vendors","published":"published"}
//jsonObjectChild GetChildNodesAPIServiceImpl ===== {"pageName":"honda0","pageTitle":"Test Honda","pagePath":"/content/country/test/grb/automobile/Vendors/honda0","published":"published"}
if (jsonObjectChild == null) continue;
if (hasNodesAsPageOrFolder(childNode)) extracted(resourceResolver, childNode, jsonObjectChild);
jsonArray.add(jsonObjectChild);
}
if (jsonArray.size() != 0) jsonObject.add("childNodes", jsonArray);
}

 

For this I have already written the below JUNIT, as shown below 

********************* JUNIT **************************

class GetChildNodesAPIServiceImplTest {

private ResourceResolverFactory resolverFactory = mock(ResourceResolverFactory.class);

private ResourceResolver resourceResolver = mock(ResourceResolver.class);

@Mock
SlingHttpServletRequest request;

@Mock
Node rootNode;

@Mock
private NodeService nodeService;

@Mock
private Session session;

@InjectMocks
GetChildNodesAPIServiceImpl getChildNodesAPIService = new GetChildNodesAPIServiceImpl();

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

@BeforeEach
void setUp() throws RepositoryException, LoginException {
MockitoAnnotations.initMocks(this);
}

@test
void testGetChildNodesResponse() throws LoginException, IOException, RepositoryException {
when(resolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
when(resourceResolver.adaptTo(Session.class)).thenReturn(session);
ServletResponse<String> actualChildNodesResponse = getChildNodesAPIService.getChildNodesResponse(
new FormsHandlingRequest(new SlingHttpServletRequestWrapper(mock(SlingHttpServletRequest.class))),
"grb", "078b036a-d536-5b8e-9893-94c92041f4d3");

assertNull(actualChildNodesResponse.getPayload());
assertEquals(ServletResponse.ServletResponseType.RES_400, actualChildNodesResponse.getStatus());
}

I have already Mock the ResourceResolverFactory and ResourceResolver as shown in above JUNIT test class but still I feel it is not going inside the try (ResourceResolver resourceResolver = getResourceResolver()) for the method getChildNodesResponse . Can you please let me know if anything is wrong I did here.