Expand my Community achievements bar.

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