cancel
Showing results for 
Search instead for 
Did you mean: 

MockSupport for Delegate Execution Beans

texens
Champ in-the-making
Champ in-the-making
Currently Activiti support Mock Support for Service Tasks if they are defined as classes.

In the BPMN file, define the service task as :

    <serviceTask id="serviceTask" activiti:class="com.yourcompany.delegate"/>


and then in the test file,

   @Test
   @Deployment
   @MockServiceTask(originalClassName="com.yourcompany.delegate",
                    mockedClassName="org.activiti.standalone.testing.helpers.ServiceTaskTestMock")
   public void testMockedServiceTaskAnnotation() {
      Assert.assertEquals(0, ServiceTaskTestMock.CALL_COUNT.get());
      activitiRule.getRuntimeService().startProcessInstanceByKey("mockSupportTest");
      Assert.assertEquals(1, ServiceTaskTestMock.CALL_COUNT.get());   
   }


Source : MockSupportWithActivitiRuleTest.java


Question : I have defined my classes in the bpmn file as delegate expression :


    <serviceTask id="serviceTask" activiti:delegateExpression="${serviceTaskBean}"/>


and in the activiti.cfg.xml file, I define these beans.

Is there a way I can mock these delegate expressions, in a way similar to the facility for service tasks defined as class (aforementioned manner).
Example :

   @MockServiceTask(originalClassName="com.yourcompany.delegate",
                    mockedClassName="org.activiti.standalone.testing.helpers.SuccessfulServiceTaskTestMock")
   public void testMockedServiceTaskSuccess() {



   @MockServiceTask(originalClassName="com.yourcompany.delegate",
                    mockedClassName="org.activiti.standalone.testing.helpers.FailedServiceTaskTestMock")
   public void testMockedServiceTaskFailure() {


The first code takes in the SuccessfulServiceTaskTestMock class in delegate, while the second code tests that the FailedServiceTaskTestMock class in delegate.

One brute force solution is to have separate activiti.cfg.xml file for each test and set the beans appropriately on a per unit test basis. But this is not scalable, as I have to update all the xml files for the test cases when I change the workflow.

Anybody has come across this scenario, and found a solution for this ?

TIA
3 REPLIES 3

jtmille3
Champ in-the-making
Champ in-the-making
I'd like to +1 this.  Any solution?

jsalmon
Champ in-the-making
Champ in-the-making
+1, I'm also looking for a nice way to mock beans referenced in expressions.

jsalmon
Champ in-the-making
Champ in-the-making
I figured out a way to achieve this using Mockito and modifying the ProcessEngineConfiguration slightly. I didn't find any better way of doing it yet.

Note: I'm using Spring Boot.

<java>
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@TestPropertySource("classpath:application.properties")
@WebIntegrationTest
public class WorkflowTest {

  /** This service is NOT being mocked */
  @Autowired
  WorkflowService workflowService;

  /** This service is being mocked */
  @Mock
  ConfigurationService configurationService;

  @Before
  public void setUp() throws Exception {
    // Initialise the mock services
    MockitoAnnotations.initMocks(this);

    // Set a MockExpressionManager on the ProcessEngineConfiguration.
    SpringProcessEngineConfiguration configuration = (SpringProcessEngineConfiguration) ProcessEngines.getDefaultProcessEngine().getProcessEngineConfiguration();
    configuration.setExpressionManager(new MockExpressionManager());

    // Register the services. Note that you need to register ALL services, even if they are not mocks,
    // otherwise the ExpressionManager and hence the process instance will not be able to resolve them.
    Mocks.register("workflowService", workflowService);  // Real service
    Mocks.register("configurationService", configurationService); // Mocked service
  }
</java>

Then the workflow will use the mock service whenever it is invoked.

If your mocked service needs to set some execution variables for later on in the workflow, you can do it with a Mockito stub:

<java>
  @Test
  public void test() throws Exception {
    // …

    doAnswer(invocation -> {
      DelegateExecution execution = (DelegateExecution) invocation.getArguments()[0];
      execution.setVariable("configured", true);
      return null;
    }).when(configurationService).execute(anyObject());

    // …
  }
</java>

Hope this helps somebody.