Testing of ExecutionListeners with JUnit & Mockito

Hi all,

I tried to use various integration and unit testing options for our spring-boot based processes. I have first checked the resources Testing examples, Process testing and Assert API.

Now we can roughly test process paths and delegate class execution unit test. However, mocking of the attributes of the classes derived from ExecutionListener does not really work, which ends up with a NPE at some point in the execution.

Based on the following code snippets and BPMN views can anyone tell me, what could be the problem? or is it the camunda internal class instantiation that differ between Listeners and Delegates?

Class under test:

@Named("ActivationLinkListener")
@Component
public class ActivationLinkListener implements ExecutionListener {

  private static final Logger LOGGER = LoggerFactory.getLogger(ActivationLinkListener.class);

  @Autowired
  private ProcessAVariables processAVars;

  @Override
  public void notify(DelegateExecution delegateExecution) {
    processAVars.setVariableScope(delegateExecution);
    Integer resendCount = processAVars.getResendCounter();
    if (smsResend == null){
      smsResend = 0;
    }
    LOGGER.info("BV Registration ActivationLinkListener called. Retry : " + resendCount++);
    processAVars.setResendCounter(smsResend);
  }
}

Test Code:

@RunWith(PowerMockRunner.class)
@Deployment(resources = "bpmn/ProcessA.bpmn")
public class ActivationLinkListenerTest extends AbstractProcessEngineRuleTest {

  @Rule
  @ClassRule
  public static ProcessEngineRule engineRule = TestCoverageProcessEngineRuleBuilder.create().build();

  @Mock
  private ProcessAVariables processAVars;

  @InjectMocks
  private ActivationLinkListener activationLinkListener;

  @Before
  public void setUp() {
    // Initialize mocks created above
    MockitoAnnotations.initMocks(this);
    Mocks.register("activationLinkListener", activationLinkListener);
  }

  @After
  public void teardown() {
    // calculate coverage for all tests
    Mocks.reset();
    cleanDeployments();
  }

  @Test
  public void startProcessAtSendActivationLinkDelegate() {

    // Intermediate given & received
    Mockito.when(regProcessVars.getResendCounter()).thenReturn(0);

    // Process run at the right task
    runProcessAtActivationLinkListener();

    // Then ...
    Mockito.verify(regProcessVars).setResendCounter(1);
  }

  private void runProcessAtActivationLinkListener() {
    VariableMap variables = Variables.createVariables()
      .putValue(ProcessAConstants.RESEND_COUNT, 1)
      .putValue(ProcessAConstants.MAX_RESEND_LIMIT, 3);

	runtimeService().createProcessInstanceByKey("ProcessA")
        .startBeforeActivity("ExclusiveGateway_1kyhy7x")
        .setVariables(variables)
        .execute();
  }


ProcessA.bpmn (7.5 KB)

Thanks a lot in advance.

Cheers
Tunç

Hi @tunch,

maybe you’re missing the initialization of the engine:

  @Before
  public void setup() {
    init(rule.getProcessEngine());
  }

Hope this helps, Ingo

Thanks @Ingo_Richtsmeier but it did not help. I believe the process engine is initialized correctly. It starts and arrives to the listener class during testing as expected. I also see that in the test thread the mocks (ProcessAVars) are set and injected correctly to the activationLinkListener.

The mocked processAVars is still simply null when the process arrives to the context of activationLinkListener. Either Mockito cannot mock it due to some Camunda internal mechanisms, or Camunda forces a new instantiation of this class during process run.
It would be really good to understand why.