Please find the below sample code .How to write Junit for workflow
Views
Replies
Total Likes
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");
}
}
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
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<>())));
Hi @Raja_Reddy thanks for ur reply getting same error .
Cannot instantiate the type WorkflowDataImpl
HI @DillipDi
You can try using ModifiableValueMapDecorator which directly implements
https://sling.apache.org/apidocs/sling7/org/apache/sling/api/wrappers/ValueMapDecorator.html
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:
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.
Hi @HrishikeshKa 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
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.
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.
Hi @sravs plz find the working code. while pasting the code here that line got changed.
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");
}
}
@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.
Views
Replies
Total Likes
@DillipDi If you have found out solution yourself, please share it with the community.
Views
Replies
Total Likes
Views
Like
Replies
Views
Likes
Replies