Test camunda methods

Hello!

Can someone help me with junit tests?
For example, i have methods i want to test.

public List<LockedExternalTask> getLockedExternalTasks(String topic, String workerId) {
    return camunda.getExternalTaskService()
            .fetchAndLock(100, workerId)
            .topic(topic, 100L)
            .includeExtensionProperties()
            .enableCustomObjectDeserialization()
            .execute();
}

public void completeExternalTask(String taskId, String workerId) {
    camunda.getExternalTaskService().complete(taskId, workerId);
}

public void createIncident(LockedExternalTask lockedExternalTask, String errorMessage) {
    camunda.getRuntimeService().createIncident(
            RUNTIME_UNRESOLVABLE_INCIDENT,
            lockedExternalTask.getExecutionId(),
            INCIDENT_CONFIGURATION,
            errorMessage);
    log.error(String.format("Incident created. %s", errorMessage), lockedExternalTask.getId());
}

public boolean ifIncidentExists(LockedExternalTask lockedExternalTask) {
    return camunda.getRuntimeService().createIncidentQuery()
            .processInstanceId(lockedExternalTask.getProcessInstanceId())
            .list().stream()
            .anyMatch(incident -> incident.getProcessInstanceId().equals(lockedExternalTask.getProcessInstanceId()));
}

Thanks for any advice/link/docs and etc.

Hello @moshell

Well, it’s difficult to unit test this kind of functionality, because it’s basically Camunda’s code - and they have an extensive unit test suite to make sure it’s working.

I would recommended that you first focus should be on unit testing your own business code components. Components that perform some kind of logic / computations that are important to your domain.

Second, you could look into testing your process to verify that your process flow / logic is correct. Such a test would most likely also test logic such as the above (assuming it’s called as part of a process, off course).

Have a look at this to read more about how to test a hole (or part of) process:

I hope that helps.

BR
Michael

Hello @mimaom

thank you so much.

here is my code

class CamundaMethodsTest {

    private CamundaMethods camundaMethods;

    private ProcessEngine usedProcessEngine = ProcessEngineConfiguration
            .createStandaloneInMemProcessEngineConfiguration()
            .setJdbcUrl("jdbc:h2:mem:camunda;DB_CLOSE_DELAY=1000")
            .buildProcessEngine();

    @RegisterExtension
    ProcessEngineExtension extension = ProcessEngineExtension
            .builder()
            .useProcessEngine(usedProcessEngine)
            .build();

    @BeforeEach
    public void setup() {
        camundaMethods = new CamundaMethods(usedProcessEngine);
    }


    @Test
    @Deployment(resources = "TestExtTask.bpmn")
    void whenExtTaskIsActiveThanGetTopicNamesReturnExpectedList() {
        // Given we create a new process instance
        ProcessInstance processInstance = runtimeService().startProcessInstanceByKey("TestExtTask");
        // Then it should be active
        assertThat(processInstance).isActive();
        // And it should be the only instance
        assertThat(processInstanceQuery().count()).isEqualTo(1);

        List<String> actualTopicNames = camundaMethods.getTopicNames();
        org.junit.jupiter.api.Assertions.assertEquals("test-topic", actualTopicNames.get(0));
    }

    @Test
    @Deployment(resources = "TestExtTask.bpmn")
    void whenExtTaskIsActiveThanGetLocketExtTaskReturnExpectedCountTask() {
        ProcessInstance processInstance = runtimeService().startProcessInstanceByKey("TestExtTask");
        List<LockedExternalTask> lockedExternalTasks = camundaMethods.getLockedExternalTasks("test-topic", "workerId");
        org.junit.jupiter.api.Assertions.assertEquals(1, lockedExternalTasks.size());
    }
}

if i run tests separately it works fine.
but if i run tests all together it fails with the error

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Таблица “ACT_HI_PROCINST” уже существует
Table “ACT_HI_PROCINST” already exists; SQL statement:

it seems like h2 database initialization runs before each test.
how to prevent this behavior?

Hi @moshell

You can either do this (use static):

    private static final ProcessEngine usedProcessEngine = ProcessEngineConfiguration
            .createStandaloneInMemProcessEngineConfiguration()
            .setJdbcUrl("jdbc:h2:mem:camunda;DB_CLOSE_DELAY=1000")
            .buildProcessEngine();

    @RegisterExtension
    private static final ProcessEngineExtension extension = ProcessEngineExtension
            .builder()
            .useProcessEngine(usedProcessEngine)
            .build();

OR (remove the manual config code) you can use the @ExtendWith like this:

@ExtendWith(ProcessEngineExtension.class)
public class ProcessTestForum {

    @Test
...

But if you want to use the @ExtendWith, you need to have an engine configuration, so add file test/resources/camunda.cfg.xml with the following:

<?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.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">

    <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="" />

    <!-- Database configurations -->
    <property name="databaseSchemaUpdate" value="true" />

    <!-- job executor configurations -->
    <property name="jobExecutorActivate" value="false" />

    <property name="history" value="full" />

    <!-- telemetry configuration -->
    <property name="telemetryReporterActivate" value="false" />

    <!-- engine plugins -->
    <property name="processEnginePlugins">
      <list>
        <ref bean="spinProcessEnginePlugin" />
      </list>
    </property>

  </bean>

  <!-- engine plugin beans -->
  <bean id="spinProcessEnginePlugin" class="org.camunda.spin.plugin.impl.SpinProcessEnginePlugin" />

</beans>

BR
Michael