JBoss Drools unit testing with junit-drools
Recently I’ve been working with a project heavily using JBoss Drools. I am not Drools expert – I am not also very convinced to this framework, or maybe only to particular use case in this project – and I found it quite difficult to write simple, maintainable unit tests for Drools based business rules.
That’s how junit-drools was born – simple helper library letting you write Drools test without putting too much boilerplate code (as you can find in Drools JBoss Rules 5.X Developer’s Guide examples).
Installation
Add Maven repository and dependency to your pom.xml:
<repository> <id>maciejwalkowiak.pl</id> <url>https://github.com/maciejwalkowiak/maven-repo/raw/releases/</url> </repository>
<dependency> <groupId>pl.maciejwalkowiak</groupId> <artifactId>junit-drools</artifactId> <version>1.0</version> <scope>test</scope> </dependency>
Usage
junit-drools provides DroolsJUnitRunner class that handles most boilerplate code you need to write to set up knowledge base and Drools session.
Lets consider following example:
@RunWith(DroolsJUnitRunner.class) @DroolsFiles(value = "helloworld.drl", location = "/drl/") public class AppTest { @DroolsSession StatefulSession session; @Test public void should_set_discount() { Purchase purchase = new Purchase(new Customer(17)); session.insert(purchase); session.fireAllRules(); assertTrue(purchase.getTicket().hasDiscount()); } @Test public void should_not_set_discount() { Purchase purchase = new Purchase(new Customer(22)); session.insert(purchase); session.fireAllRules(); assertFalse(purchase.getTicket().hasDiscount()); } }
- @RunWith(DroolsJUnitRunner) – inits JUnit runner for testing drools rules
- @DroolsFiles – set location of drl files (can be one or multiple) – drl files have to be on class path – @DroolsFiles#location is relative to
src/test/resources
orsrc/main/resources
- @DroolsSession – autoinjects Drools session to your test before execution
Find full example with drl file in src/test directory of the project on Github.
In case you don’t want to use DroolsJUnitRunner, for example because you already want to use Mockito or Spring runner you can initialize Drools objects in @Before method:
@DroolsFiles(value = "helloworld.drl", location = "/drl/") public class BeforeMethodBasedTest { @DroolsSession StatefulSession session; @Before public void initDrools() throws Exception { new DroolsInjector().initDrools(this); } @Test public void should_set_discount() { Purchase purchase = new Purchase(new Customer(17)); session.insert(purchase); session.fireAllRules(); assertTrue(purchase.getTicket().hasDiscount()); } }
I am not very experienced with Drools so the library actually does what was needed in project I was working with. You are welcome to add your improvements by sending pull requests into Github project.