Camunda Junit5 Unknown property used in expression

My Bpmn flow working Fine with all tasks with spring boot start up. Trying to local test setup with junit5 to do entire process test. Getting the below error

org.camunda.bpm.engine.ProcessEngineException: Unknown property used in expression: ${delegateExpressionDelegator}. Cause: Cannot resolve identifier ‘delegateExpressionDelegator’

cfg:

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

Junit:

ExtendWith(ProcessEngineExtension.class)
public class ProcessEngineTest {

// @RegisterExtension
// ProcessEngineExtension extension = ProcessEngineExtension.builder()
// .configurationResource(“camunda.cfg.xml”)
// .build();

@Test
@Deployment(resources = "cib-job-role-t24-sync.bpmn20.xml")
public void testHappyPath() {




    Map variables = new HashMap<>();

    variables.put(ExecutionVariableConstants.ID, xxxxxx);
  
    ProcessInstance processInstance = processEngine().getRuntimeService().startProcessInstanceByKey("Process Key",variables);
   
   assertThat(processInstance).isStarted().isWaitingAt("serviceTask1");

Hello @surind ,

great that you are testing processes! This is totally important and will increase quality of your process software.

As you are using expressions, you will need an expression manager for testing. This is the MockExpressionManager.

This needs to be configured in the camunda.cfg.xml.

Then, you can register the bean you try to call with

Mocks.register(„myFancyBean“, new MyFancyBeanWithANoArgsConstructor());

Please have a look here: How to Mock Camunda Expression

I hope this helps

Jonathan

Thanks Jonathan for the reply. I have tried MockExpressionManager but not working. I am dynamically passing the activity id and using the same delegateExression for all the service tasks which would have required args constructor.

@Named(value = “delegateExpressionDelegator”)
@Slf4j
@RequiredArgsConstructor
public class DelegateExpressionDelegator implements DelegateExpressionListener {

private final ActivityBeanMapper<DelegateExpressionListener> activityBeanMapper;

@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
    log.info("Well done -- DelegateExpressionSplitter");

    final var beanId = delegateExecution.getCurrentActivityId();
    DelegateExpressionListener delegateExpressionListenerTask = activityBeanMapper.getBeanByActivityId(
            beanId);
    delegateExpressionListenerTask.execute(delegateExecution);
}

}

@Component
@Slf4j
@RequiredArgsConstructor
public class ActivityBeanMapper {

private final BeanFactory beanFactory;

public DelegateExpressionListener getBeanByActivityId(@NotBlank final String beanName) {
    log.debug("Get Instance for Service Bean [{}]", beanName);
    return getBeanFromFactory(beanName);

}

private DelegateExpressionListener getBeanFromFactory(final String beanName) {
    try {
        return beanFactory.getBean(beanName,
                DelegateExpressionListener.class);
    } catch (BeansException beansException) {
        log.error("Exception while fetching bean for Service = [{}] is [{}]", beanName, beansException);
        throw new BpmnError("No Mapping found for Service Bean".concat( beanName));
    }
}

public T getBeanByActivityId(@NotBlank final String beanName, final Class<T> clazz) {
        log.info("Get Instance for Service Bean [{}]", beanName);
        return getBeanFromFactory(beanName, clazz);
}

private T getBeanFromFactory(@NotBlank final String beanName, final Class<T> clazz) {
    try {
        return beanFactory.getBean(beanName, clazz);
    } catch (BeansException beansException) {
        log.error("Exception while fetching bean for Service = [{}] is [{}]", beanName, beansException);
        throw new BpmnError("No Mapping found for Service Bean [{}]".concat( beanName));
    }
}

}

@Component(value = “serviceTaskActivityId”)
@Slf4j
@RequiredArgsConstructor
public class ServiceTaskListener extends DelegateExpressionListener {
log.info(“Business-Key [{}] ServiceTaskListener with Activity_ID >> [{}]”, delegateExecution.getVariable(ExecutionVariableConstants.BUSINESS_KEY),
delegateExecution.getCurrentActivityId());
}

Appreciate your help

The issue is resolved after adding Asynchronous Before for all the service tasks