Mock or Skip execution of ScriptTasks during process testing

I’m testing a process containing a Script Task using the following dependencies
image

    <dependency>
      <groupId>org.camunda.bpm</groupId>
      <artifactId>camunda-engine</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.camunda.bpm</groupId>
      <artifactId>camunda-bpm-junit5</artifactId>
      <version>7.20.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.camunda.community.process_test_coverage</groupId>
      <artifactId>camunda-process-test-coverage-junit5-platform-7</artifactId>
      <version>${camunda-process-test-coverage.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.camunda.bpm</groupId>
      <artifactId>camunda-bpm-assert</artifactId>
      <version>7.20.0</version>
      <scope>test</scope>
  </dependency>
    <dependency>
      <groupId>org.camunda.bpm.extension</groupId>
      <artifactId>camunda-bpm-assert-scenario</artifactId>
      <version>1.1.1</version>
      <scope>test</scope>
    </dependency>
  <dependency>
    <groupId>org.openjdk.nashorn</groupId>
    <artifactId>nashorn-core</artifactId>
    <version>15.4</version>
    <scope>test</scope>
</dependency>
    <dependency>
      <groupId>org.camunda.bpm.extension.scenario</groupId>
      <artifactId>camunda-platform-scenario-cucumber</artifactId>
      <version>2.0.0.alpha.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.camunda.bpm.extension.mockito</groupId>
      <artifactId>camunda-bpm-mockito</artifactId>
      <scope>test</scope>
      <version>4.13.0</version>
  </dependency>

and this is my testing class

@ExtendWith(ProcessEngineExtension.class)
@ExtendWith(ProcessEngineCoverageExtension.class)
@Deployment(resources = { "bpmn/jam-handling_phase1.bpmn", "bpmn/jam-handling_phase2.bpmn", "bpmn/jam-handling_phase3.bpmn" })
public class ProcessTest {

    @Mock private ProcessScenario jamHandlingPhase1;
    @Mock private ProcessScenario jamHandlingPhase2;
    @Mock private ProcessScenario jamHandlingPhase3;

    public ProcessEngine processEngine;


    @BeforeEach
    void setup() {
        MockitoAnnotations.openMocks(this);
        
    }

    @Test
    public void testPhase1_AtmStatusOk() {
        when(jamHandlingPhase1.waitsAtServiceTask("Activity_0biqdj4"))
        .thenReturn(task -> task.complete(
            Variables.createVariables().putValue("abi", "0000").putValue("terminal", "1111")
        ));

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_055b9uy"))
            .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtUserTask("Activity_0it20yv"))
        .thenReturn(task -> task.complete(Variables.createVariables().putValue("atmStatusOK", true)));

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_0ycjfiu"))
            .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_0wv82yx"))
            .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_1c3zka0"))
            .thenReturn(task -> task.complete());

        final Map<String, Object> variables = Variables.createVariables();
        variables.put("ticketId", "ABCDEFGHI12345");
        variables.put("correlationId", "12345678ABCDEFGH");

        Scenario scenario = Scenario.run(jamHandlingPhase1) //
            .startByKey("jam-handling_phase1", variables) //
            .execute();

        assertThat(scenario.instance(jamHandlingPhase1)).variables().containsEntry("ticketId", "ABCDEFGHI12345");
        assertThat(scenario.instance(jamHandlingPhase1)).variables().containsEntry("correlationId", "12345678ABCDEFGH");
        assertThat(scenario.instance(jamHandlingPhase1)).variables().containsEntry("atmStatusOK", true);

        verify(jamHandlingPhase1).hasFinished("Event_101ddfa");
    }

    @Test
    public void testPhase1_AtmStatusNotOk() {
        when(jamHandlingPhase1.waitsAtServiceTask("Activity_0biqdj4"))
        .thenReturn(task -> task.complete(
            Variables.createVariables().putValue("abi", "0000").putValue("terminal", "1111")
        ));

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_055b9uy"))
            .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtUserTask("Activity_0it20yv"))
        .thenReturn(task -> task.complete(Variables.createVariables().putValue("atmStatusOK", false)));

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_1ltgo7j"))
        .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_0ycjfiu"))
            .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_0wv82yx"))
            .thenReturn(task -> task.complete());

        when(jamHandlingPhase1.waitsAtServiceTask("Activity_1c3zka0"))
            .thenReturn(task -> task.complete());

        final Map<String, Object> variables = Variables.createVariables();
        variables.put("ticketId", "ABCDEFGHI12345");
        variables.put("correlationId", "12345678ABCDEFGH");

        Scenario scenario = Scenario.run(jamHandlingPhase1) //
            .startByKey("jam-handling_phase1", variables) //
            .execute();

        assertThat(scenario.instance(jamHandlingPhase1)).variables().containsEntry("ticketId", "ABCDEFGHI12345");
        assertThat(scenario.instance(jamHandlingPhase1)).variables().containsEntry("correlationId", "12345678ABCDEFGH");
        assertThat(scenario.instance(jamHandlingPhase1)).variables().containsEntry("atmStatusOK", false);
        
        verify(jamHandlingPhase1).hasFinished("Event_101ddfa");
    }

}

Is there a way to Mock or skip the execution of the Script Task?
I was forced to implement the Nashorn engine in order to execute the script, but I would prefer to Mock the Script Task as any other Service Task.

Hi @fenix-hub,

as the scripts are directly executed on the JVM within the thread of the process instance, I assume that there is no way to provide a mock for it.

Hope this helps, Ingo

Thank you @Ingo_Richtsmeier ,
so isn’t there any way to test a process without actually executing the script?

You could write an interceptor for the process model loader. There, you would replace the the script task element with something else that fits your test. Or you change the model and make this step a service task. The script would be executed as part of the implementation. Then you’ll have a good chance to mock it.