BPM assert (hasPassedInOrder) and async service tasks

Hello,
I have modeled a simple BPMN process with two Tasks:

StartEvent --> TaskOne --> TaskTwo --> EndEvent

To test the BPMN model, I created the following UnitTest, which works fine as long as ‘asynchronous before’ is not checked at any of the service tasks.

@Deployment(resources = { "process.bpmn" })
public class ProcessTest {

	@Rule
	public ProcessEngineRule processEngineRule = new ProcessEngineRule();

	@Mock
	private Process process;

	@Before
	public void init() {
		MockitoAnnotations.initMocks(this);
		Mocks.register("process", process);
	}

	@Test
	public void test() {
		RuntimeService runtimeService = processEngineRule.getRuntimeService();
		ProcessInstance processInstance = runtimeService.createProcessInstanceByKey("process").execute();
		assertThat(processInstance).hasPassedInOrder(new String[] { "Activity_TaskOne", "Activity_TaskTwo" });
		assertThat(processInstance).isEnded();
	}
}

After checking ‘asynchronous before’ at both service tasks, the unit test outputs:

java.lang.AssertionError: Expecting org.camunda.bpm.engine.impl.persistence.entity.ProcessInstanceWithVariablesImpl@21c815e4 
to have passed activities [Activity_TaskOne, Activity_TaskTwo] at least once and in order,
but actually we instead we found that it passed [StartEvent].
(Please make sure you have set the history service of the engine to at least 'activity' or a higher level before making use of this assertion!)

As far as I understand asychronous continuations this makes sense, but how can this be solved? Are there any other possibilities to unit test process flows with async service tasks or do I something wrong?

Hey,

in this unit test setup, there is no JobExecutor running to perform your asynchronous jobs.

You need to push them forward manually in your test:

assertThat(processInstance).isWaitingAt("YourAsyncActivity");
BpmnAwareTests.execute(BpmnAwareTests.job());

Hello,
thanks for your suggestion.
The JobExecutor is actually configured in the camunda.cfg.xml:

<bean id="processEngineConfiguration" class="org.camunda.bpm.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
	<property name="dataSource" ref="dataSource" />
	<property name="databaseSchemaUpdate" value="true" />
	<property name="jobExecutorActivate" value="true" />
	<property name="history" value="full" />
</bean>

When setting the ‘jobExecutorActivate’ to ‘false’, something like the following works:

RuntimeService runtimeService = processEngineRule.getRuntimeService();
ProcessInstance processInstance = runtimeService.createProcessInstanceByKey("process").execute();
assertThat(processInstance).hasPassed(new String[] { "StartEvent" });
assertThat(processInstance).isWaitingAt("Activity_TaskOne");
execute(job());
assertThat(processInstance).isWaitingAt("Activity_TaskTwo");
execute(job());
assertThat(processInstance).isEnded();

This would be a little bit unhandy for huge BPMN processes. Of course, I could write my own implementation of a ‘hasPassedInOrder’ and switch of the JobExecutor, but I expect that such an issue has been solved before and that there’s a simple solution also when the JobExecutor has been activated.

Hi @peterg,

if you enable the jobExecutor for the test, you have to wait until the job is done. Maybe a Thread.sleep(1000) is sufficient, maybe not (it depends on your hardware).

I see the

assertThat(processInstance).isWaitingAt("Activity_TaskOne");
execute(job());

as a visual marker in the test to hop over the asynchronous continuation.

And tests are much faster, as you don’t need to wait for the job acquisition in the database.

My preference is to run the tests with jobExecutor.

Hope this helps, Ingo