JUnit-Testing for Message Events

Hi all,

I tried to Unit-Test a process. It is basically the case that I have a simple task. That is completed

complete(task(), allVars);

In my process there will then be several service tasks that get executed automatically. Then the last event will be a Message throw event. This event calls a different deployment and starts its process by

ProcessInstance pi = runtimeService.startProcessInstanceByMessage(MESSAGE_START_NAME, businessKey, variables);

Now I have the problem that
a) JUnit cannot find the other Process
b) Even when I put the bpmn file of the other process in my tests/resources folder and reference it in my test class, like @Deployment(resources = { "x.dmn", "y.bpmn"}) it does not work.

So the question is
a) How to Unit-test such a setting?
b) Can I stop the Unit test at the message throw event and start a second Test that then begins at the catch event so I leave out the external sub process?

Cheers!

Your approach sounds right. I think you are just missing some configuration. To help you with that, could you upload your unit test on github?

You can start a process instance in any state of activity instances, see Testing | docs.camunda.org

@thorben
thanks for your reply.

I will upload the test later. However - and maybe thats already sufficient for an answer, please find attached the process diagram

The point is when you complete the User-Task then the engine runs further through the “do stuff” task until the message event. The message is fired and then the (not deployed) sub process shall be fired. The error occurs as the engine does not find a message catch / message start event as it is obviously in the other process.

As the engine automatically runs until the message event, the question is. How do I stop the JUnit Test there and after the “do stuff”?

Then of course I could start a second test at the message catch event. But the crucial question is, how to stop at or before the message is tried to send. The “do stuff” must be executed in any case as the outcome is relevant for the test.

P.S. In case I put an asynchronus after at the “do stuff” the engine would stop there. But there is no way to change the process model just for testing purposes.

I think we should try to figure out why the process you try to start is not deployed. I think that is easier to resolve than trying to work around this problem by avoiding the message throw event being executed.

Hi,

If you want to unit-test your process, you should do it in an isolated way. I would try avoid calling other processes in a unit-test, neither using call-activities nor through messages. You want to test the behaviour of the first process and you don’t want your unit-test to break, if there is a bug in the other process.

If your message throw event uses a JavaDelegate, you can easily register a delegate mock for it and prevent the other process from being called (don’t forget to unit-test the delegate as well).

How about that approach?

Edit: Of course, Thorben’s approach is still valid, if your other process does not deploy, you should figure out why. I propose to have an isolated unit-test for that as well, just to figure out if it works on its own. The first and simplest unit-test, that I always write, is:

@Test
@Deployment(resource = "x.bpmn")
public void shouldDeploy() {}

One more Edit: Above you wrote that @Deployment(resources = { "x.dmn", "y.bpmn"}) does not work, and I noticed that one of the resources is a DMN file, not a BPMN file. Maybe just a typo, but better double-check.

Cheers,
Stefan

@stefanzilske

thanks for your reply. I agree with you that I am not keen on testing both processes at once. Therefore I don’t want the message to be thrown. I am interested in a delegate mock in order to prevent the message being thrown. Do you have a code example for this?

P.S . @Deployment(resources = { "x.dmn", "y.bpmn"}) is indeed a typ, it should have been @Deployment(resources = { "x.bpmn", "y.bpmn"})

If you followed the Camunda testing guide so far, I assume that you already have the necessary Dependencies, especially camunda-bpm-mockito. If not, checkout https://github.com/camunda/camunda-bpm-mockito.

You can easily register a mock with

DelegateExpressions.registerJavaDelegateMock("yourMockName");

(yourMockName has to match the delegate expression in your process model)

You can also stub this mock e.g. to set some process variables, checkout the documentation on GitHub.

Cheers,
Stefan