Software Develoment Journey
Java, Spring Framework, How-to

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:

1
2
3
4
<repository>
    <id>maciejwalkowiak.pl</id>
    <url>https://github.com/maciejwalkowiak/maven-repo/raw/releases/</url>
</repository>
1
2
3
4
5
6
<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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@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 or src/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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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.

If you enjoyed this post, then make sure you subscribe to my RSS feed