Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

How to load a json in a MockJcr inside a unit test?

Avatar

Level 4

How could you load a json with test data into a MockJcr inside a Java Unit test? 

 

I know it is possible to load a mock json into an AemContext, e,g, 

 

 

@ExtendWith(AemContextExtension.class)
@ExtendWith(MockitoExtension.class)
class MyTest {

    final AemContext context = new AemContext();

    @Mock
    private Session session;

    private final String PROPERTY = "myproperty";

    private final String[] ARGS={"myvalue"};

    @BeforeEach
    void setup() {
        context.registerAdapter(WorkflowSession.class, Session.class, session);
        context.load().json("/pages/MyPage.json", "/content/page");
    }

    public void myWorkflowViaSling() throws WorkflowException {
        String[] values = context.resourceResolver().getResource("/content/page/jcr:content").getValueMap().get(PROPERTY, ARG);
        assertEquals(ARGS,values);
    }
}

 

 

But is there a way to load a mock json into a MockJcr?

 

 

class MyWorkflowTest {
    
    private final String PROPERTY = "myproperty";

    private final String ARGS={"myvalue"};
    
    public void myWorkflowViaJCR() throws Exception {
        Session mockSession = MockJcr.newSession();

        // Here, I am adding nodes 1 by 1 and setting their properties, where it would be simpler to load a json
        mockSession.getRootNode().addNode("jcr:content").setProperty(PROPERTY, ARGS);

        Value[] valueMap = mockSession.getNode("/" + "jcr:content").getProperty(PROPERTY).getValues();
        assertEquals(ARGS[0],valueMap[0].getString());
    }
}

 

 

Topics

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

1 Accepted Solution

Avatar

Correct answer by
Level 4

I found a working solution to load JSON data into a mock JCR.

 

@ExtendWith(AemContextExtension.class)
@ExtendWith(MockitoExtension.class)
class MyTest {

    private final AemContext jcrContext = new AemContext(ResourceResolverType.JCR_MOCK);

    private final Session jcrSession = jcrContext.resourceResolver().adaptTo(Session.class);
    
    private final String PROPERTY = "myproperty";

    private final String ARGS={"myvalue"};
    
    @test
    public void myTestViaJCR() throws Exception {
        assertNotNull(jcrSession);

        jcrContext.registerAdapter(WorkflowSession.class, Session.class, jcrSession);
        jcrContext.load().json("/pages/MyPage.json", "/content/page");

        Node root = jcrSession.getRootNode();
        Node newNode = root.addNode("content").addNode("page").addNode("jcr:content");
        newNode.setProperty(PROPERTY, ARGS);
        jcrSession.save();

        Node node = jcrSession.getNode("/" + "content" + "/" + "page" + "/" + "jcr:content");
        assertNotNull(node);

        Property property = node.getProperty(PROPERTY);
        assertNotNull(property);

        Value[] valueMap = property.getValues();
        assertNotNull(valueMap);

        assertEquals(ARGS[0],valueMap[0].getString());
    }
}

 

View solution in original post

5 Replies

Avatar

Community Advisor

Why can't you use the AemContextExtension?

Avatar

Level 4

I can. But the road less travled is more interesting.  
Also, I needed this approach to be able to test a workflow.

Avatar

Community Advisor

Hi @jeremylanssiers - check this, if it helps

@Rule
    public final AemContext context = new AemContext();

    @Test
    public void testLoadJsonFile() throws RepositoryException, JSONException {
        // Add test node to Mock JCR
        Session session = context.resourceResolver().adaptTo(Session.class);
        Node node = session.getRootNode().addNode("content/myresource", "nt:unstructured");
        node.setProperty("myproperty", "myvalue");
        session.save();

        
        InputStream is = getClass().getResourceAsStream("/mytest.json");
        JSONObject jsonObject = new JSONObject(new JSONTokener(is));
        context.load().json(jsonObject, "/content/myresource");

        Node testNode = session.getNode("/content/myresource");
        assertNotNull(testNode);
    }
}

Avatar

Level 4

This still results in testNode being null. Does it not for you?

 

I believe the mock JCR is different from the mock AEM context. 

 

Only adding nodes into the MockJcr works. 

Avatar

Correct answer by
Level 4

I found a working solution to load JSON data into a mock JCR.

 

@ExtendWith(AemContextExtension.class)
@ExtendWith(MockitoExtension.class)
class MyTest {

    private final AemContext jcrContext = new AemContext(ResourceResolverType.JCR_MOCK);

    private final Session jcrSession = jcrContext.resourceResolver().adaptTo(Session.class);
    
    private final String PROPERTY = "myproperty";

    private final String ARGS={"myvalue"};
    
    @test
    public void myTestViaJCR() throws Exception {
        assertNotNull(jcrSession);

        jcrContext.registerAdapter(WorkflowSession.class, Session.class, jcrSession);
        jcrContext.load().json("/pages/MyPage.json", "/content/page");

        Node root = jcrSession.getRootNode();
        Node newNode = root.addNode("content").addNode("page").addNode("jcr:content");
        newNode.setProperty(PROPERTY, ARGS);
        jcrSession.save();

        Node node = jcrSession.getNode("/" + "content" + "/" + "page" + "/" + "jcr:content");
        assertNotNull(node);

        Property property = node.getProperty(PROPERTY);
        assertNotNull(property);

        Value[] valueMap = property.getValues();
        assertNotNull(valueMap);

        assertEquals(ARGS[0],valueMap[0].getString());
    }
}