Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Unable to Mock Node and Set Properties in JUnit

Avatar

Level 1

I have a function to convert node properties to json object and need to unit test that function. But I have tried many ways to mock the node but still getting null value.

 

public class NodePropertiesImpl{

public JSONObject getNodeProperties(Node node) {
JSONObject nodeJson = new JSONObject();
try {
nodeJson.put("componentGroup", getValueFromProperty(node, "group"));
nodeJson.put("componentTitle", getValueFromProperty(node, "jcr:title"));
nodeJson.put("componentPath", node.getPath());
} catch (Exception ex) {
log.error(ex.getMessage());
}
return nodeJson;
}

public String getValueFromProperty(Node node, String propertyKey) {
String propertyVal = new String();
try {
if(node.hasProperty(propertyKey)){
propertyVal = node.getProperty(propertyKey).getValue().toString();
}
} catch (Exception e) {
log.error(e.getMessage());
}
return propertyVal;
}
}

 

 

Here's the unit test:

 

public class NodePropertiesImplTest extends AbstractTest  {
private NodePropertiesImpl nodeImpl;
@Mock
private Node node;
private Resource resource;
private Property property;

@Before
public final void setUp() throws Exception {
nodeImpl= new NodePropertiawImpl();
context.registerInjectActivateService(nodeImpl);
}

@Test
public void WHEN_NodeHasProperties_RETURN_AllNodePropertiesInJSON() throws JSONException, RepositoryException {
//Arrange
Node node = Mockito.mock(Node.class);
node.setProperty("nodeName", "node name is Hello");
node.setProperty("NodePath", "wcm/foundation/components/responsivegrid");

//Act
JSONObject actualJson = nodeImpl.getNodeProperties(node);
//Assert

}
}

 The node parameter is null even though the properties are set. I was wondering what's the correct syntax for this?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hello @codingninja 

 

You would need to set up Mocks like this:

 

    @Test
    public void testGetNodeProperties() throws RepositoryException, JSONException {
        // Arrange
        when(node.getPath()).thenReturn("/some/path");
        when(node.hasProperty("group")).thenReturn(true);
        when(node.hasProperty("jcr:title")).thenReturn(true);
        Property groupProperty = Mockito.mock(Property.class);
        Property titleProperty = Mockito.mock(Property.class);
        when(node.getProperty("group")).thenReturn(groupProperty);
        when(node.getProperty("jcr:title")).thenReturn(titleProperty);
        when(groupProperty.getValue()).thenReturn("Group Value");
        when(titleProperty.getValue()).thenReturn("Title Value");

        // Act
        JSONObject result = nodeImpl.getNodeProperties(node);

        // Assert
        assertEquals("Group Value", result.getString("componentGroup"));
        assertEquals("Title Value", result.getString("componentTitle"));
        assertEquals("/some/path", result.getString("componentPath"));
    }

 For every object used, initialization needs to be done.


Aanchal Sikka

View solution in original post

5 Replies

Avatar

Community Advisor

@codingninja Could you try something similar and test it out?

context.create().resource("/content/page1", "group", "groupvalue", "jcr:title", "Title1");
// get resource resolver
ResourceResolver resourceResolver = context.resourceResolver();


Resource resource1 = resourceResolver.getResource("/content/page1");
assertNotNull(resource1);
Node  node = resource1.adaptTo(Node.class);
JSONObject actualJson = nodeImpl.getNodeProperties(node);
assertEquals("groupvalue", actualJson.getString("group"));

 

Avatar

Level 1

I have tried your code but the node is still null for some reason

Avatar

Correct answer by
Community Advisor

Hello @codingninja 

 

You would need to set up Mocks like this:

 

    @Test
    public void testGetNodeProperties() throws RepositoryException, JSONException {
        // Arrange
        when(node.getPath()).thenReturn("/some/path");
        when(node.hasProperty("group")).thenReturn(true);
        when(node.hasProperty("jcr:title")).thenReturn(true);
        Property groupProperty = Mockito.mock(Property.class);
        Property titleProperty = Mockito.mock(Property.class);
        when(node.getProperty("group")).thenReturn(groupProperty);
        when(node.getProperty("jcr:title")).thenReturn(titleProperty);
        when(groupProperty.getValue()).thenReturn("Group Value");
        when(titleProperty.getValue()).thenReturn("Title Value");

        // Act
        JSONObject result = nodeImpl.getNodeProperties(node);

        // Assert
        assertEquals("Group Value", result.getString("componentGroup"));
        assertEquals("Title Value", result.getString("componentTitle"));
        assertEquals("/some/path", result.getString("componentPath"));
    }

 For every object used, initialization needs to be done.


Aanchal Sikka

Avatar

Level 1

Thanks for your reply.

 

I modified your code a little to be like this:

@Test
public void testGetNodeProperties() throws RepositoryException, JSONException {
// Arrange
node = Mockito.mock(Node.class);
when(node.getPath()).thenReturn("/some/path");
when(node.hasProperty("group")).thenReturn(true);
when(node.hasProperty("jcr:title")).thenReturn(true);
Property groupProperty = Mockito.mock(Property.class);
Property titleProperty = Mockito.mock(Property.class);
when(node.getProperty("group")).thenReturn(groupProperty);
when(node.getProperty("jcr:title")).thenReturn(titleProperty);
when(groupProperty.getValue().getString()).thenReturn("Group Value");
when(titleProperty.getValue().getString()).thenReturn("Title Value");

// Act
JSONObject result = nodeImpl.getNodeProperties(node);

// Assert
assertEquals("Group Value", result.getString("componentGroup"));
assertEquals("Title Value", result.getString("componentTitle"));
assertEquals("/some/path", result.getString("componentPath"));
}

 but i got this error:

java.lang.IllegalArgumentException: Classpath resource not found: /home.json
 
at org.apache.sling.testing.mock.sling.loader.ContentLoader.json(ContentLoader.java:175)
at com.microsoft.mcb.tests.unit.mocks.AbstractTest.getDefaultContent(AbstractTest.java:103)
at com.microsoft.mcb.tests.unit.mocks.AbstractTest.setup(AbstractTest.java:123)
 
Do you know why this is the case? 

Avatar

Community Advisor

Hello @codingninja 

 

Can you please check for occurence of "/home.json" in your code?

May be its used in the AbstractTest that the classes extends.

 

Please share the code relevant to the same.


Aanchal Sikka