Software Design Blog

Journey of Rinat Abdullin

Using Lokad Rules to Simplify .NET Unit Tests

Recently I’ve been doing some work deep in the code of a Desktop Windows.Forms application by replacing generic hand-written Validators with Lokad Rules (this allowed to drop quite a few classes, by the way).

Along with the process, I found myself using Lokad Rules for writing unit tests. Take a look at these NUnit statements in C#:

Assert.IsTrue(visitor.Programs.Exists(p => p.Active),
  "'visitor' should have at least one active program");

Assert.IsTrue(visitor.Programs.Length > 1,
  "'visitor' should have more than one program");

It looks much better this way, does not it:

RuleAssert.That(() => visitor, 
  v => v.Programs.Exists(p => p.Active),
  v => v.Programs.Length > 1);

With this approach, we don’t have to bother about writing description, mentioning the exact name the name of the variable and keeping these in sync. The RuleException, being thrown, will contain all the information that we need:

visitor: Expression should be true: v => v.Programs.Exists(p => p.Active).

This has been done by introducing a new dynamic rule Is.True{T}. Given a lambda expression, it compiles a standard rule and generates an error message for it.

That’s how assertion will look like, if rewritten to use that rule explicitly:

var compiled1 = Is.True<Visitor>(v => v.Programs.Exists(p => p.Active);
var compiled2 = Is.True<Visitor>(v => v.Programs.Length > 1);

Enforce.That(() => visitor, compiled1, compiled2));

Obviously, RuleAssert class allows to have syntax that is much shorter, since in testing we don’t care about the slight overhead of compiling expressions.

RuleAssert could be found in Lokad.Shared.dll of Lokad Shared Libraries. It has a few other methods as well. I’ll talk about them in more detail later (in short, that’s a simple fluent API for testing your domain rules developed with Lokad Business Rules Application Block).

  • What do you think about it so far?
  • Would you use this RuleAssert syntax to make your unit tests more efficient and easy to maintain?
  • How could it be improved?