How to write Junit for workflow | Community
Skip to main content
May 2, 2024

How to write Junit for workflow

  • May 2, 2024
  • 5 replies
  • 2809 views

Please find the below sample code .How to write Junit for workflow

 

public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) {
            ResourceResolver resourceResolver = null;
        try {
Session session = workflowSession.adaptTo(Session.class);
Map<String, Object> map = new HashMap<>();
map.put(mysession, session); 
resourceResolver=resourceResolver.getResourceResolver(resourceResolverFactory, map);
WorkflowData workflowData = workItem.getWorkflowData();
String path = workflowData.getPayload().toString();  
  Resource resource = resourceResolver.getResource(path);
ValueMap valuemap = resource.getValueMap();
String prop = valueMap.get("dc:title", String.class);
Resource metadataresource = resourceResolver.getResource(resource.getPath() + "/metadata");
ModifiableValueMap mvaluemap = metadataresource.adaptTo(ModifiableValueMap.class);
mvaluemap.put(mymetadata:title, prop);
 
 
    } catch (Exception e) {
logger.info("my exception", e.getMessage());
    }
     } 
Any suggestion will really help. Thanks
This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

5 replies

Raja_Reddy
Community Advisor
Community Advisor
May 2, 2024

Hi @dillipdi 

1.Create a mock WorkItem, WorkflowSession, and MetaDataMap objects.

2.Create a mock ResourceResolver object using a mocking framework like Mockito.

3.Mock the required methods of the ResourceResolver object to return the expected values.

4.Create an instance of the class containing the execute method.Call the execute method with the mock objects.

5.Verify that the expected methods of the mock objects were called with the expected parameters.

import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.Map; import javax.jcr.Session; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class WorkflowTest { @Mock private WorkItem workItem; @Mock private WorkflowSession workflowSession; @Mock private MetaDataMap metaDataMap; @Mock private ResourceResolverFactory resourceResolverFactory; @Mock private ResourceResolver resourceResolver; @Mock private Session session; @Mock private Resource resource; @Mock private Resource metadataResource; private Workflow workflow; @Before public void setUp() throws Exception { Map<String, Object> map = new HashMap<>(); map.put("mysession", session); when(resourceResolverFactory.getResourceResolver(map)).thenReturn(resourceResolver); when(workItem.getWorkflowData()).thenReturn(new WorkflowData(new ValueMapDecorator(new HashMap<>()))); when(workItem.getWorkflowData().getPayload()).thenReturn("/content/sample"); when(resourceResolver.getResource("/content/sample")).thenReturn(resource); ValueMap valueMap = new ValueMapDecorator(new HashMap<>()); valueMap.put("dc:title", "Sample Title"); when(resource.getValueMap()).thenReturn(valueMap); when(resourceResolver.getResource("/content/sample/metadata")).thenReturn(metadataResource); ModifiableValueMap mValueMap = new ValueMapDecorator(new HashMap<>()); when(metadataResource.adaptTo(ModifiableValueMap.class)).thenReturn(mValueMap); workflow = new Workflow(); } @Test public void testExecute() throws Exception { workflow.execute(workItem, workflowSession, metaDataMap); verify(resourceResolverFactory).getResourceResolver(anyMap()); verify(workItem).getWorkflowData(); verify(workItem.getWorkflowData()).getPayload(); verify(resourceResolver).getResource("/content/sample"); verify(resource).getValueMap(); verify(resourceResolver).getResource("/content/sample/metadata"); verify(metadataResource).adaptTo(ModifiableValueMap.class); verify(metadataResource.adaptTo(ModifiableValueMap.class)).put("mymetadata:title", "Sample Title"); } }
DillipDiAuthor
May 2, 2024

Hi @raja_reddy Thanks for ur quick reply . I tried the above code getting error like 

Cannot instantiate the type WorkflowData
Type mismatch: cannot convert from ValueMapDecorator to ModifiableValueMap

 

 

Raja_Reddy
Community Advisor
Community Advisor
May 2, 2024

Try this

 

Replace WorkflowData with WorkflowDataImpl in the setUp() method. ValueMapDecorator with ModifiableValueMapDecorator in the setUp() method.

 

when(workItem.getWorkflowData()).thenReturn(new WorkflowDataImpl(new ValueMapDecorator(new HashMap<>()))); 

 

 

HrishikeshKagne
Community Advisor
Community Advisor
May 3, 2024

Hi @dillipdi ,

To write JUnit tests for workflows, you need to simulate the workflow execution and then verify that the expected actions are performed. In your case, you want to test the execute method of your workflow process step. Here's how you can write JUnit tests for it:

 

import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.commons.testing.sling.MockResourceResolver; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import javax.jcr.Node; import javax.jcr.Session; import java.util.HashMap; import java.util.Map; @RunWith(MockitoJUnitRunner.class) public class YourWorkflowProcessTest { @Mock private WorkItem workItem; @Mock private WorkflowSession workflowSession; @Mock private Session session; private YourWorkflowProcess workflowProcess; @Before public void setUp() throws Exception { workflowProcess = new YourWorkflowProcess(); } @Test public void testExecute() throws Exception { // Mocking payload path and title String payloadPath = "/content/sample"; String title = "Sample Title"; // Mocking resource resolver MockResourceResolver resourceResolver = new MockResourceResolver(); // Mocking resource and metadata resource Resource payloadResource = Mockito.mock(Resource.class); Mockito.when(payloadResource.getPath()).thenReturn(payloadPath); Resource metadataResource = Mockito.mock(Resource.class); Mockito.when(resourceResolver.getResource(payloadPath + "/metadata")).thenReturn(metadataResource); // Mocking value map for payload resource Map<String, Object> payloadProperties = new HashMap<>(); payloadProperties.put("dc:title", title); ValueMap payloadValueMap = new ValueMapDecorator(payloadProperties); Mockito.when(payloadResource.getValueMap()).thenReturn(payloadValueMap); // Mocking modifiable value map for metadata resource Map<String, Object> metadataProperties = new HashMap<>(); Mockito.when(metadataResource.adaptTo(ModifiableValueMap.class)).thenReturn(new ValueMapDecorator(metadataProperties)); // Mocking workflow data WorkflowData workflowData = Mockito.mock(WorkflowData.class); Mockito.when(workItem.getWorkflowData()).thenReturn(workflowData); Mockito.when(workflowData.getPayload()).thenReturn(payloadResource); // Mocking session Mockito.when(workflowSession.adaptTo(Session.class)).thenReturn(session); // Executing the workflow process workflowProcess.execute(workItem, workflowSession, new MetaDataMap()); // Verifying if the title property is set in metadata Mockito.verify(metadataResource, Mockito.times(1)).adaptTo(ModifiableValueMap.class); Mockito.verify(metadataResource.adaptTo(ModifiableValueMap.class), Mockito.times(1)).put("mymetadata:title", title); } }

 

In this test:

  • We mock the necessary objects such as WorkItem, WorkflowSession, ResourceResolver, etc.
  • We set up mock behavior for methods used within the execute method.
  • We execute the execute method of the workflow process.
  • We verify that the expected actions, such as setting the title property in metadata, are performed.

Make sure to replace YourWorkflowProcess with the actual name of your workflow process class. This test verifies that the workflow process performs the expected actions when executed.

Hrishikesh Kagane
DillipDiAuthor
May 3, 2024

Hi @hrishikeshkagne thanks for ur time to reply .i tried ur above code but getting the below error

 

java.lang.ClassCastException: class org.apache.sling.api.wrappers.ValueMapDecorator cannot be cast to class org.apache.sling.api.resource.ModifiableValueMap

HrishikeshKagne
Community Advisor
Community Advisor
May 3, 2024

Hi @dillipdi ,

It seems like you're trying to mock the adaptation of a resource to a ModifiableValueMap using ValueMapDecorator, which is causing the ClassCastException. The issue lies in this line:

 

Mockito.when(metadataResource.adaptTo(ModifiableValueMap.class)).thenReturn(new ValueMapDecorator(metadataProperties));

 

ValueMapDecorator does not implement ModifiableValueMap, so you cannot cast it directly. Instead, you should mock the ModifiableValueMap interface directly.

Here's how you can fix it:

 

// Mocking modifiable value map for metadata resource ModifiableValueMap metadataValueMap = Mockito.mock(ModifiableValueMap.class); Mockito.when(metadataResource.adaptTo(ModifiableValueMap.class)).thenReturn(metadataValueMap);

 

 Then, you can use metadataValueMap to manipulate properties:
// Setting properties on the mock ModifiableValueMap
metadataValueMap.put("mymetadata:title", title);
By doing this, you are properly mocking the ModifiableValueMap interface, avoiding the ClassCastException.

Hrishikesh Kagane
sravs
Community Advisor
Community Advisor
May 3, 2024

Hi @dillipdi ,

 

I can see some issue with the code which you have shared.

resourceResolver=resourceResolver.getResourceResolver(resourceResolverFactory, map);

There is no such method in resourceResolver object and that to you are trying to call that method on a null object which you have defined at starting of the method.

 

Please check whether the snippet you have shared is correct or not, if possible try to share complete class.

 

 

 

DillipDiAuthor
May 3, 2024

Hi @sravs plz find the working code. while pasting the code here that line got changed.

 

public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) {
            ResourceResolver resourceResolver = null;
        try {
Session session = workflowSession.adaptTo(Session.class);
Map<String, Object> map = new HashMap<>();
map.put(mysession, session); 
resourceResolver = resourceResolverFactory.getResourceResolver(map);
WorkflowData workflowData = workItem.getWorkflowData();
String path = workflowData.getPayload().toString();  
  Resource resource = resourceResolver.getResource(path);
ValueMap valuemap = resource.getValueMap();
String prop = valueMap.get("dc:title", String.class);
Resource metadataresource = resourceResolver.getResource(resource.getPath() + "/metadata");
ModifiableValueMap mvaluemap = metadataresource.adaptTo(ModifiableValueMap.class);
mvaluemap.put(mymetadata:title, prop);
 
 
    } catch (Exception e) {
logger.info("my exception", e.getMessage());
    }
     } 
sravs
Community Advisor
Community Advisor
May 3, 2024

Hi @dillipdi ,

 

Can you please try with below snippet

import com.adobe.granite.workflow.WorkflowSession; import com.adobe.granite.workflow.exec.WorkItem; import com.adobe.granite.workflow.exec.WorkflowData; import com.adobe.granite.workflow.metadata.MetaDataMap; import com.adobe.granite.workflow.metadata.SimpleMetaDataMap; import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.ResourceResolverFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import javax.jcr.Session; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Mockito.when; @ExtendWith({MockitoExtension.class, AemContextExtension.class}) class YourWorkflowProcessTest { private AemContext context = new AemContext(); @InjectMocks private YourWorkflowProcess workflowProcess; @Mock WorkflowData payload; @Mock WorkItem workItem; @Mock WorkflowSession workflowSession; @Mock Session session; @Mock ResourceResolverFactory resourceResolverFactory; @Test void execute() throws LoginException { String path = "/content/dam/sample/resource"; String metaPath = "/content/dam/sample/resource/metadata"; context.create().resource(path,"dc:title","Sample"); context.create().resource(metaPath, "jcr:primaryType","nt:unstructured"); when(workflowSession.adaptTo(Session.class)).thenReturn(session); when(resourceResolverFactory.getResourceResolver(anyMap())).thenReturn(context.resourceResolver()); when(workItem.getWorkflowData()).thenReturn(payload); when(payload.getPayload()).thenReturn(path); MetaDataMap map = new SimpleMetaDataMap(); workflowProcess.execute(workItem, workflowSession, map); String metaProp = context.resourceResolver().getResource(metaPath).getValueMap().get("mymetadata:title", String.class); assertEquals(metaProp, "Sample"); } }
kautuk_sahni
Community Manager
Community Manager
May 16, 2024

@dillipdi Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.

Kautuk Sahni
kautuk_sahni
Community Manager
Community Manager
May 20, 2024

@dillipdi If you have found out solution yourself, please share it with the community.

Kautuk Sahni