Camunda Testcase: Mocking same call activity once with message boundary event and once without message boundary event

Hi Team,

I have Camunda workflow in which I have call activity with called element “SUB-PROCESS-ID” multiple times. In one of the call activity I have message boundary event and in rest other call I don’t need message boundary event. Currently I’m using below code snippet for mocking the call activity

ProcessExpressions.registerCallActivityMock(“SUB-PROCESS-ID”)
.onExecutionSetVariables()
.deploy();

If I use “.onExecutionWaitForMessage(“MESSAGE_NAME”)” then it will get added to all the call activity in the workflow but I need to add “onExecutionWaitForMessage” only once. Please help me how to resolve the issue to mock same call activity multiple times in same workflow with different scenario once with message boundary event and once without message boundary event and next time with different output variables

Couldn’t it be enough if you register the call activityMock in each separate test method? So not as Test-Instance property but test-method variable?

Hi jangalinski , Thanks for your reply. That might not work because I have single work main flow which calls one same sub process in call activity 2 times with different scenario, once I need the call activity to wait till I receive the massage from boundary event and once no need to wait. I’m attaching my BPMN and test case for the reference. If I use:

ProcessExpressions.registerCallActivityMock(“CALL_SUB_PROCESS”)
.deploy(processEngineRule);

then it throws error for message correlation: Error while evaluating expression: ${execution.getProcessEngineServices().getRuntimeService().createMessageCorrelation(“READ_MESSAGE2”).processInstanceId(execution.getProcessInstanceId()).correlate()}. Cause: org.camunda.bpm.engine.MismatchingMessageCorrelationException: Cannot correlate message ‘READ_MESSAGE2’: No process definition or execution matches the parameters

If I use:

ProcessExpressions.registerCallActivityMock(“CALL_SUB_PROCESS”)
.onExecutionWaitForMessage(“READ_MESSAGE2”)
.deploy(processEngineRule);

it is throwing null pointer exception. Please help to resolve the issue

message-send-receive.bpmn (10.1 KB)

Please find the test case code below:

@Test
@Deployment(resources = { “bpmn/sample/message-send-receive.bpmn” })
public void test() {
ProcessInstance processInstance = runtimeService().startProcessInstanceByKey(“message_send_receive”, withVariables(“id”, “123456”));
assertThat(processInstance).isStarted().isActive();

// ProcessExpressions.registerCallActivityMock(“CALL_SUB_PROCESS”).deploy(processEngineRule);
ProcessExpressions.registerCallActivityMock(“CALL_SUB_PROCESS”).onExecutionWaitForMessage(“READ_MESSAGE2”).deploy(processEngineRule);

	assertThat(processInstance).isWaitingAt("Activity_0673hrr");
	claim(task(), "Mahantesh");
	complete(task());
	
	ManagementService managementService = processEngineRule.getManagementService();
	
	assertThat(processInstance).isWaitingAt("Event_14ino9k");	
	Job job1 = managementService.createJobQuery()
	  		.processInstanceId(processInstance.getProcessInstanceId())
	  		.activityId("Event_14ino9k")
	  		.singleResult();
	managementService.executeJob(job1.getId()); // Explicitly execute the activity in case of async after or before is true
	
	assertThat(processInstance).isWaitingAt("Activity_01mn86d");
	claim(task(), "Mahantesh");
	complete(task());
	
	assertThat(processInstance).isWaitingAt("Activity_1ev3ahp");	
	Job job2 = managementService.createJobQuery()
	  		.processInstanceId(processInstance.getProcessInstanceId())
	  		.activityId("Activity_1ev3ahp")
	  		.singleResult();
	managementService.executeJob(job2.getId()); // Explicitly execute the activity in case of async after or before is true
	
	assertThat(processInstance).isWaitingAt("Activity_0yoyyxy");
	claim(task("Activity_0yoyyxy"), "Mahantesh");
	complete(task("Activity_0yoyyxy"));
	
	assertThat(processInstance).isWaitingAt("Event_0nr2j3b");
	Job job3 = managementService.createJobQuery()
			.processInstanceId(processInstance.getProcessInstanceId())
			.activityId("Event_0nr2j3b")
			.singleResult();
	managementService.executeJob(job3.getId());// Explicitly execute the activity in case of async after or before is true
	
	assertThat(processInstance).isWaitingAt("Activity_1d6n2nv");
	claim(task("Activity_1d6n2nv"), "Mahantesh");
	complete(task("Activity_1d6n2nv"));
	
	assertThat(processInstance).isEnded();
}

Depending on the steps in “Check Message”, it could be completing before the message arrives, which then means that the boundary event is no longer listening.

Try putting a User Task in “Check Message” that you complete without waiting for the message on your happy path, and then check to see that the process overall is waiting at the user task in the Event Subprocess. If it’s waiting on “Check Message” in the event subprocess, you should be able to throw the message that is expected for the boundary event to get to “User Task4 (Subprocess)”

This isn’t really a clean design. General rule is that you cannot throw a message and catch it in the same process. Looking at the process, it’s really hard to tell what you’re trying to convey. Best guess is that what you currently have as an event subprocess should be a process on its own.

@jangalinski did you get a chance to look at above issue, i have shared bpmn and test case. please let me know if any other information is required

@GotnOGuts Thanks for the suggestion but the one I shared is the sample created to replicate the PROD workflow issue. Issue is I need to mock sub-process call activity which is used multiple times in same main workflow which once may have different outputs and once have message boundary event.