我正在尝试将一个规则作为一个单元运行,以测试我的应用程序。我们按单元运行的原因是因为这些规则包含一些相当复杂的业务逻辑,需要对其进行全面测试。我们确实有其他测试可以整体运行整个会话,但是这些测试的粒度不足以涵盖单个规则的业务逻辑。因此,我们阅读了所有“请勿测试单个规则”文章,但由于我们的特定用例,还是决定这样做。
无论如何,我遇到的实际问题是我们尝试应用的RuleNameEqualsAgendaFilter似乎没有我们希望的预期行为。尽管我既指定了重点议程组,又在运行规则时应用了过滤器,但无论如何,似乎都对所有规则进行了评估。这导致无法测试两个在相同条件下触发的规则。
我已经包括了测试代码和一些示例规则,它们在结构上与我们的运行方式相似。
测试
@Slf4j
public class MyUnitTest {
@Test
public void myRuleTest() {
MyFact myFact = new MyFact();
KieSession kieSession = getKieSessionWithFacts("myAgendaGroup", myFact);
fireSpecificRule(kieSession, "My First Rule");
}
private KieSession getKieSession(String agendaGroup) {
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("TEST");
kieSession.setGlobal("logger", log);
kieSession.getAgenda().getAgendaGroup(agendaGroup).setFocus();
return kieSession;
}
private KieSession getKieSessionWithFacts(String agendaGroup, Object... facts) {
KieSession kieSession = getKieSession(agendaGroup);
for (Object fact : facts) {
kieSession.insert(fact);
}
return kieSession;
}
private void fireSpecificRule(KieSession kieSession, String ruleName) {
kieSession.fireAllRules(new RuleNameEqualsAgendaFilter(ruleName));
}
}
规则
rule "My First Rule"
agenda-group "myAgendaGroup"
no-loop true
when
MyFact()
then
logger.info("Fired my first rule");
end
rule "My Second Rule"
agenda-group "myAgendaGroup"
no-loop true
when
MyFact()
then
logger.info("Fired my second rule");
end
rule "My Unrelated Rule"
agenda-group "myOtherAgendaGroup"
no-loop true
when
MyFact()
then
logger.info("Fired my unrelated rule");
end
我们在测试日志中看到的输出如下:
这意味着不仅过滤器不限制触发 myAgendaGroup 中的哪些规则,而且触发 myOtherAgendaGroup 中的规则。
我希望能够开除第一条规则。我想念什么?