Camunda junit testing for externalTask; externalTask() returns null

HI,

I’m using below camunda.cfg.xml to setup my processEngine and then added a unit test to complete my first task, which is externalTask with topicName as task_1. When i run this test case i’m getting nullpointerException and i see that externalTask() returns null. Am i missing some setup for processEngine ?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="processEngineConfiguration" class="org.camunda.bpm.extension.process_test_coverage.junit.rules.ProcessCoverageInMemProcessEngineConfiguration">
		
		<property name="jdbcUrl" value="jdbc:h2:mem:camunda;DB_CLOSE_DELAY=1000" />
	    <property name="jdbcDriver" value="org.h2.Driver" />
	    <property name="jdbcUsername" value="sa" />
	    <property name="jdbcPassword" value="" />
	    
        <property name="history" value="full" />
        <property name="databaseSchemaUpdate" value="true" />
        <property name="jobExecutorActivate" value="false" />
        <property name="processEngineName" value="test-engine"/>
        <property name="telemetryReporterActivate" value="false"/>
        <property name="expressionManager">
            <bean class="org.camunda.bpm.engine.test.mock.MockExpressionManager" />
        </property>
        <property name="idGenerator">
            <bean class="org.camunda.bpm.engine.impl.persistence.StrongUuidGenerator"/>
        </property>

    </bean>
</beans>
@RunWith(MockitoJUnitRunner.class)
@Deployment(resources = {"dummyWorkflow.bpmn"})
public class DummyProcessWithMessageTest {
    private static final String PROCESS_KEY = "spikeWorkflow";

    @Rule
    public ProcessEngineRule rule = new ProcessEngineRule();

    @Test
    public void dummyTask1Working() {
    	// given
        ProcessInstance instance = runtimeService().startProcessInstanceByKey(PROCESS_KEY);

        // assume
        assertThat(instance)
                .isActive()
                .hasPassed("start")
                .isWaitingAtExactly("task_1");
        
        // when
        complete(externalTask()); // **** Errors here with null external task.
        
        // then
        assertThat(instance).isWaitingAtExactly("task_2");
    }
}

Hi @kallsas,

what happens if you extend your assertion to the external task:

// assume
        assertThat(instance)
                .isActive()
                .hasPassed("start")
                .isWaitingAtExactly("task_1").externalTask().hasTopicName("Id don't know"); 

I assume that you get an assertionError here, if the external task is null.

Hope this helps, Ingo

That’s correct, as externalTask() is returning null the above said assertion fails as the error states ‘Expecting assertion to be called on non-null object, but found to be null’. I still don’t understand why the externalTask() would return null though. I’m following the example stated here - process-testing/TestNextMatch.java at master · camundacon2019/process-testing · GitHub and see that the bpmn has an external task with a topic, that should basically get subscribed and worked upon, which is what i have exactly.

On a different note, I’m trying to understand what all the unit tests would cover here ? I mean, if i can just complete or move the tasks to the next stage without having to trigger my actual subscription code for each of the external tasks, what am i achieving here ? is it just that the flow will happen regardless of the code that i have inside my java delegate/single function ? I will be calling an external API and update some tables in the actual function. How do i test those methods ?

Hi @kallsas,

Most likely, because the current task of the asserted process instance is not an external task.

The unit test checks all assertions on the process model. You can check if all expressions after gateways are working as expected and you don’t have any typos or other mistakes here.

It will check if the task is an external task and has the given topic name.

For user task tasks, you can check the assignment.

There are other scopes that require different tests like integration tests or acceptance tests: Testing | docs.camunda.org

Hope this helps, Ingo

Thanks for the response. I understood what is happening with the externalTask returning null. I have defined the external tasks as asynchronous before and seems like we don’t need to do it anymore as they’re already a save point, according to one of your previous comment’s i found here - UnitTest for BPMN-workflow with an external task - #6 by Ingo_Richtsmeier.

I will check the integration tests and other scopes link above. I do have one last question here, if we don’t need to specify an external task as Asynchronous before then why do we have the checkbox on this item in camunda modeler ? Will this be fixed in future release ? Thanks

Hi @kallsas,

Maybe you have listener code attached that you want to save with additional save points.

Hope this helps, Ingo