Mock Drools ObjectFactory, KieSession and StatelessKieSession using Junit

This tutorial example will show you how to mock ObjectFactory<KieSession>, KieSession and KieStatelessSession using Junit.

KieSession is the most common way to interact with the engine in Drools.

A KieSession allows the application to establish an iterative conversation with the engine, where the state of the session is kept across invocations.

The reasoning process may be triggered multiple times for the same set of data. After the application finishes using the session, though, it must call the dispose method in order to free the resources and used memory.

StatelessKieSession implements CommandExecutor which can be used to script a KieSession.


Prerequisites
Knowledge of Java, Junit
Spring dependencies
Junit Mockito framework dependency

The first example we will see about mocking ObjectFactory<KieSession> and KieSession.

Suppose you have this below Spring service class where you have @Autowired ObjectFactory<KieSession> from which you get KieSession for doing your business flows.

@Service
public class DroolsServiceOne {
    @Autowired
    private ObjectFactory<KieSession> kieSessionFactory;
    public void triggerRequiredFieldsRules(Object contextEntity, String ruleName) {
        KieSession kieSession = kieSessionFactory.getObject();
        //more code...
    }
}

Now when you will write a junit class for the above service class, you don’t want to build a real KieSession. Instead you want to mock ObjectFactory<KieSession>.

Writing Junit class

Your junit class should look similar to below class. In this class we have mocked ObjectFactory<KieSession> and KieSession to return the mock object.

@RunWith(MockitoJUnitRunner.class)
public class DroolsServiceOneTest {
    @Mock
    private ObjectFactory<KieSession> kieSessionFactory;
    @Mock
    private KieSession kieSession;
    @Spy
    @InjectMocks
    private final DroolsServiceOne ruleService = new DroolsServiceOne();
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }
    @Test
    public void testTriggerRequiredFieldsRules() throws Exception {
        Mockito.when(kieSessionFactory.getObject()).thenReturn(kieSession);
        //more code...
        Object object = new Object();
        ruleService.triggerRequiredFieldsRules(object, "rule");
        //finally you may verify your method
        Mockito.verify(ruleService, Mockito.times(1)).triggerRequiredFieldsRules(object, "rule");
    }
}

In the above junit class we mocked the ObjectFactory<KieSession> and KieSession. Then we injected those mock objects into the real object of service class.

Finally we initialize all mock objects using init method before running the test case.

Now look at the below second example where you will see how to mock StatelessKieSession object.

Let’s say you have the following Spring service class where you have the following @Autowird StatelessKieSession object for your Drools activity.

@Service
public class DroolsServiceTwo {
    @Autowired
    private StatelessKieSession kieSession;
    public void triggerRequiredFieldsRules(Object contextEntity) {
        kieSession.execute(contextEntity);
    }
}

Writing Junit class

Your junit class should look similar to below class where we have mocked StatelessKieSession to return the mock object.

@RunWith(MockitoJUnitRunner.class)
public class DroolsServiceTwoTest {
    @Mock
    private StatelessKieSession kieSession;
    @Spy
    @InjectMocks
    private final DroolsServiceTwo rulesService = new DroolsServiceTwo();
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }
    @Test
    public void testTriggerRequiredFieldsRules() throws Exception {
        Mockito.doNothing().when(kieSession).execute(Mockito.any(Object.class));
        Object object = new Object();
        rulesService.triggerRequiredFieldsRules(object);
        Mockito.verify(rulesService, Mockito.times(1)).triggerRequiredFieldsRules(object);
   }
}

That’s all about how to mock ObjectFactory<KieSession>, KieSession and KieStatelessSession using Junit.

You may check here why you see @Spy annotation in the test cases.

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *