How to JUnit test DMN using Junit 5 (Jupiter)?

Hello All,

We are developing small process that will automate certain manual processes in our organization using Camunda Platform 7. Each process is an application (NOT SPRING BOOT). Some of the processes have DMN. I want to write JUnit test cases to test out the DMN. We wish to use the JUnit 5 (Jupiter).
However i am unable to test. Either it is not able to find the DMN when i use decisionService (that is derived from ProcessEngines.getDefaultProcessEngine(false).getDecisionService(); or if i use the DecisionEngineRule approach then the JUnit fails to run saying "

java.lang.NoClassDefFoundError: org/junit/rules/TestWatcher
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:757)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
	at java.lang.Class.getDeclaredFields0(Native Method)
	at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
	at java.lang.Class.getDeclaredFields(Class.java:1916)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:1392)
	at org.junit.platform.commons.util.ReflectionUtils.findAllFieldsInHierarchy(ReflectionUtils.java:1150)
	at org.junit.platform.commons.util.ReflectionUtils.findFields(ReflectionUtils.java:1138)
	at org.junit.platform.commons.util.AnnotationUtils.findAnnotatedFields(AnnotationUtils.java:371)
	at org.junit.platform.commons.util.AnnotationUtils.findAnnotatedFields(AnnotationUtils.java:348)
	at org.junit.jupiter.engine.descriptor.ExtensionUtils.registerExtensionsFromFields(ExtensionUtils.java:99)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:148)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:78)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:141)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.ClassNotFoundException: org.junit.rules.TestWatcher
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
	... 51 more

"

Either way i am blocked and unable to move forward. Some examples or guidance will really help and i appreciate it in advance.

The dependencies in pom.xml are: -

<properties>
		<failOnMissingWebXml>false</failOnMissingWebXml>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<jira-rest-java-client-core.version>5.2.4</jira-rest-java-client-core.version>
		<io.atlassian.fugue.version>5.0.0</io.atlassian.fugue.version>
		<jackson-core.version>2.9.6</jackson-core.version>
		<jackson-annotations.version>2.9.6</jackson-annotations.version>
		<jackson-databind.version>2.9.6</jackson-databind.version>
		<jackson-dataformat-yaml.version>2.9.6</jackson-dataformat-yaml.version>
		<apache.poi.version>5.2.2</apache.poi.version>
		<apache.poi-ooxml.version>5.2.2</apache.poi-ooxml.version>
		<failOnMissingWebXml>false</failOnMissingWebXml>
		<this.bitbucket.project.key>ccbcore</this.bitbucket.project.key>
		<this.bitbucket.project.key.lowercase>ccbcore</this.bitbucket.project.key.lowercase>
		<this.jira.project.key>ccbcore</this.jira.project.key>
		<this.confluence.space.key>ccbcore</this.confluence.space.key>
		<slf4j-jdk14.version>2.0.4</slf4j-jdk14.version>
		<camunda.version>7.18.0</camunda.version>
		<spring.version>5.3.22</spring.version>
		<commons-email.version>1.5</commons-email.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.camunda.bpm</groupId>
				<artifactId>camunda-bom</artifactId>
				<version>${camunda.version}</version>
				<scope>import</scope>
				<type>pom</type>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-framework-bom</artifactId>
				<version>${spring.version}</version>
				<scope>import</scope>
				<type>pom</type>
			</dependency>
			<dependency>
				<groupId>com.atlassian.jira</groupId>
				<artifactId>jira-rest-java-client-core</artifactId>
				<exclusions>
					<exclusion>
						<groupId>org.slf4j</groupId>
						<artifactId>slf4j-api</artifactId>
					</exclusion>
				</exclusions>
			</dependency>
			<dependency>
			    <groupId>com.atlassian.jira</groupId>
			    <artifactId>jira-api</artifactId>
			    <exclusions>
						<exclusion>
							<groupId>commons-logging</groupId>
							<artifactId>commons-logging</artifactId>
						</exclusion>
					</exclusions>
			    <!--  <scope>provided</scope>-->
			</dependency>
			<dependency>
				<groupId>org.camunda.bpm.assert</groupId>
				<artifactId>camunda-bpm-assert</artifactId>
				<version>15.0.0</version>
			</dependency>
			
			
			<dependency>
				<groupId>org.camunda.bpm.dmn</groupId>
				<artifactId>camunda-engine-dmn-bom</artifactId>
				<version>${camunda.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>

		
		</dependencies>
		
		
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.camunda.bpm</groupId>
			<artifactId>camunda-engine</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.camunda.bpm</groupId>
			<artifactId>camunda-engine-spring</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>${jackson-core.version}</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>${jackson-annotations.version}</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson-databind.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-email</artifactId>
			<version>${commons-email.version}</version>
		</dependency>


		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>1.4.199</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.atlassian.jira</groupId>
			<artifactId>jira-rest-java-client-core</artifactId>
			<version>${jira-rest-java-client-core.version}</version>
		</dependency>


		<dependency>
			<groupId>io.atlassian.fugue</groupId>
			<artifactId>fugue</artifactId>
			<version>${io.atlassian.fugue.version}</version>
		</dependency>
		
		
		<!-- https://mvnrepository.com/artifact/com.atlassian.jira/jira-api -->
		<dependency>
		    <groupId>com.atlassian.jira</groupId>
		    <artifactId>jira-api</artifactId>
		    <version>9.1.0-QR-20220513102649</version>
		    <scope>provided</scope>
		</dependency>
				
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>${apache.poi.version}</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
		<dependency>
		    <groupId>org.apache.poi</groupId>
		    <artifactId>poi-ooxml</artifactId>
		    <version>${apache.poi-ooxml.version}</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
		<dependency>
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-core</artifactId>
		    <version>2.17.2</version>
		</dependency>
		
		<dependency>
		  <groupId>com.fasterxml.jackson.dataformat</groupId>
		  <artifactId>jackson-dataformat-yaml</artifactId>
		  <version>${jackson-dataformat-yaml.version}</version>
		</dependency>


		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-jdk14</artifactId>
			<version>${slf4j-jdk14.version}</version>
		</dependency>
		
		<dependency>
			<groupId>org.assertj</groupId>
			<artifactId>assertj-core</artifactId>
			<version>3.22.0</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.camunda.bpm.assert</groupId>
			<artifactId>camunda-bpm-assert</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- <dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-junit-jupiter</artifactId>
			<version>4.9.0</version>
			<scope>test</scope>
		</dependency> -->
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>4.9.0</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.camunda.bpm.extension</groupId>
			<artifactId>camunda-bpm-junit5</artifactId>
			<version>1.1.0</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter</artifactId>
			<version>5.6.2</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.camunda.bpm.dmn</groupId>
			<artifactId>camunda-engine-dmn</artifactId>
		</dependency>
	</dependencies>

Hi @patkaromkar,

I found that you use an old version of the camunda-bpm-junit5 library.

You should replace it with this maven dependency: Testing | docs.camunda.org. The community extension was merged into the Camunda code base.

I usually test DMN decision with code like this:

  @Test
  @Deployment(resources = "simple.dmn")
  public void testSimpleDmn() {
    Map<String, Object> variables = withVariables(
        "input1", "value1", 
        "input2", "value2");
    
    DmnDecisionRuleResult result = decisionService()
        .evaluateDecisionTableByKey("mydecision")
        .variables(variables)
        .evaluate()
        .getFirstResult();
    
    assertThat(result).containsEntry("result1", "value3");
  }

The assertion requires the import of

import static org.assertj.core.api.Assertions.*;

Hope this helps, Ingo

1 Like

Thank you @Ingo_Richtsmeier for the quick reply… it really helps. I tried suggestion you have provided. I updated the dependency of camunda-bpm-junit5 library in pom.xml however, decisionService() is not available. What needs to be done in this regard ? Please check the screenshot below: -

Am i missing anything @Ingo_Richtsmeier

Hi @patkaromkar,

it’s coming from a static import:

import static org.camunda.bpm.engine.test.assertions.bpmn.BpmnAwareTests.*;

Hope this helps, Ingo

1 Like

ok let me quickly try that…do i need to annotate the JUnit class with : -

@ExtendWith(ProcessEngineCoverageExtension.class)
and
import org.camunda.community.process_test_coverage.junit5.platform7.ProcessEngineCoverageExtension;
available due to dependency : -

<dependency>
			<groupId>org.camunda.community.process_test_coverage</groupId>
			<artifactId>camunda-process-test-coverage-junit5-platform-7</artifactId>
			<!-- <artifactId>camunda-process-test-coverage-junit5-platform-8</artifactId> -->
			<version>${camunda-process-test-coverage.version}</version>
			<scope>test</scope>
		</dependency>

and following bean in camunda.cfg.xml

<bean id="processEngineConfiguration"
          class="org.camunda.community.process_test_coverage.engine.platform7.ProcessCoverageInMemProcessEngineConfiguration">

    </bean>

Thanks @Ingo_Richtsmeier … after the use of static import you have mentioned i was able to access “decisionService()” … however, now compiler complains for “assertThat()” :frowning:

Also, when using evaluateDecisionTableByKey(). … the 1st argument …is it the value of the id attribute or name attribute of <decision> … Or… is it the value of id attribute of <decisionTable> in the .dmn file ?

Many thanks in advance

@Ingo_Richtsmeier i found it, the assertThat() is available from the static import: -

import static org.assertj.core.api.Assertions.assertThat;

and also the key is the value of id attribute of <decision> in the .dmn file.

Thank you very much for your help, really appreciate it. :smiley: