Popular Categories
« Building VSTO Solutions Without Visual Studio | Main | Structuring .NET Applications with Autofac IoC »
Friday
Feb132009

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?

References (2)

References allow you to track sources for this article, as well as articles that were written in response to this article.

Reader Comments (4)

It seems like you're reinventing NUnit's constraint model (Assert.That).

Please see
http://www.nunit.org/index.php?p=constraintModel&r=2.4.8

February 13, 2009 | Unregistered CommenterBill Sorensen

Bill,

can you implement this trivial constraint in 1 line of code in NUnit and get complete description if it fails?

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

I don't think so.

February 14, 2009 | Registered CommenterRinat Abdullin

It's really cool that you can generate the error message, it always bugs me having to write descriptive errors for test code.

February 16, 2009 | Unregistered CommenterJacob Stanley

Very cool.

February 25, 2009 | Unregistered CommenterNick
Comments for this entry have been disabled. Additional comments may not be added to this entry at this time.