Monday 9 February 2009

Unfinished BizNess?

So I had a few BizTalk / rules engine business rules that I wanted to set up some unit tests for.  I'd been steered towards using BizUnit (in which I'll admit to having limited experience), and I was looking into the FactBasedRuleEngineStep.

Just what I needed, it seemed. But long story short, it doesn't quite work like what it oughta....
BizUnit's over on CodePlex, and though the latest code isn't in the source repository, it is included as part of the downloadable MSI.  With a little bit of looking through the  code (expedient, what with the help file being one of those overly literal types that explains that the "WidgetFooStartDate parameter" is the "Parameter indicating the date on which the Foo Widget starts", and what with the rest of the web seemingly only proving that any other people trying to use this particular "step" can't use it), I not only got the policy to fire but also got an XML file and an instance of my custom helper-class passed in.  An output file gets created by the rules engine at the location specified by the <debugtracking> element, and it was all starting to look good.

But...

I can't find any evidence that the <resultfilepath> does anything (and it certainly doesn't seem to).  Your processed document / documents *are* output, but seemingly only to the "Context's" log (which seems by default to be the [nUnit] console).  I imagine you could redirect that output elsewhere, but I didn't really look very hard what with not being in the mood to bother parsing the output to extract my result XML.

I couldn't build the BizUnit source as I was missing some Office interops and some MQ (or was it MSMQ?) dependencies (and again, I wasn't of a mind...), but there looked to be a nice little way to intercept the output-facts just by implementing my own class that implements the IValidatorStep interface (wozzit?).... but oh no, it seems that that's only going to get executed if the DocumentType is "UBS.CLAS.PoC.Schemas.INSERTS".  By the code-comment's own admission, this was a //HACK, so I can only assume it was the document type that BizUnit's author/s needed to test for.

Checking the source code (similar if not identical for this "step" in both 2.3 and 3.0) it appears that there's a unit-test to test the FactBasedRuleEngineStep.  But it also appears to have been commented out...

And one last problem:  no evidence found that the takeFromCtx attribute does anything for this particular fact (though I'd kinda given up by then).

So okay, that might have come off as a bit of a rant.  I realise that a man called Kevin threw this thing out into the world for free, that he's probably not actually paid to work on this thing and that I've certainly paid nothing for it.  Obviously the source is available, so I could have dug in and fixed this issue myself, but a custom fork of an open-source project isn't the kind of legacy I like to leave in a client's source-control system.  (I'm not inclined to submit a patch to the project itself after seeing a few others on CodePlex that appear to have been awaiting approval for a year or more...)  Anyway, my point is:  Don't try to use the FactBasedRuleEngineStep to test your rules and expect it to work.

[I ended up coding something along these lines....
TypedXmlDocument typedXmlDocument = new Microsoft.RuleEngine.TypedXmlDocument("Your.Namespace.Plus.Schema.Name.Plus.Root.Element", xmlDoc);
Policy policy = new Microsoft.RuleEngine.Policy("ContactPointLoad");

//Also need to supply a CustomXmlHelper fact!
object[] args = new object[] { typedXmlDocument, new CustomXmlHelper() };
policy.Execute(args);
policy.Dispose();
return (XmlDocument)typedXmlDocument.Document;
]

Hope that saves a googling-someone a bit of working it out for themselves...