Sunday, December 13, 2009

NUnit and Microsoft Contracts library

I’m using NUnit and Microsoft Code Contracts library to implement unit tests and code contracts (mostly preconditions).

Unfortunately Contracts library throws a generated (internal) exception class that can’t be used as Assert.Throws<ContractException>(…).

Contracts documentation suggests the following code for MSTest framework:

[TestClass]
public  class  Test
{
    [AssemblyInitialize]
    public  static  void   AssemblyInitialize (TestContext tc)
    {
        Contract. ContractFailed+= (sender, e) => {
            e.SetHandled();
            e.SetUnwind(); // cause code to  abort  after  event
            Assert.Fail(e.FailureKind.ToString() + ":" + e.DebugMessage);
        };
    }
}

I wrote the following code to mimic this functionality:

[TestFixtureSetUp]
public void SetUpFixture()
{
    Contract.ContractFailed +=
    (sender, e) =>
    {
        e.SetHandled();
        e.SetUnwind();
        Assert.Fail(string.Format("{0}:{1}", e.FailureKind.ToString(), e.Message));
    };
}

Well, it did not work, I couldn’t make the Assert.Throws structure work. I always got the ContractException exception. Finally I found a blog entry (in German) with a classic solution:

  1. use try/catch block
  2. check exception type name

So here is the working code:

try
{
    // Method under test
}
catch (Exception ex)
{
    Assert.True(ex.GetType().Name == "ContractException");
    return;
}
Assert.Fail("ContractException has not been thrown.");