Ramping Up .Net For BDD and Unit Testing With Gallio, NBehave, and Moq

Scott StultsMarch 19, 2008

Unit Testing is a word that has inspired some or has become a bane for others. TDD, test driven development, has changed the way many people write their code, and others… not so much. Then a new catch phrase appeared on the test scene, BDD, behavior driven development. So instead of tests, you’re writing specifications of expected behaviors and observations in code, that will also hopefully create your specifications documentation for you. Also there is this notion of doing story boards as well.

Ruby has Rspec built on top of a well oiled web application framework known as Rails. So where does leave .Net developers, especially with the Asp.Net Mvc Option/framework on the horizon? I’ve been keeping an eye on .net tools that would allow or be the Rpec for .net. Things like NSpec and NBehave popped up on Google, but there was really no documentation, read me’s or even blog postings to demonstrate how to use these libraries. However a cool mock library named Rhino mock became the rage to heal the pain of NMock (but geeze man, all that “Replay” stuff is confusing, totally ignoring the KISS principle). And MbUnit, a unit testing on crack, which built on top of other Xunit frameworks, seemed to be stagnated.

Enter 2008, the year of open source and openness for developers of .Net. MbUnit has been hard at working on Gallio, the neutral test platform, NBehave has merged with Nspec and Behave# and have an April 4th release date, but you can still play with the bits. Even Microsoft is doing the release often and having open input on the Asp.Net Mvc framework. A new cooler mock framework has come out known as Moq that uses the c# 3.0 extensions and lambdas, which Scott Hanselman gave a great overview about.

Gallio, the good looking, time saving, neutral testing platform, saved me from time crunching with beating CC.NET into generating what would have been another ugly Unit Test report. Gallio took around 5 minutes after reading the walk through. It also allowed for me create the Unit Testing and NCover Report at the same time running it from an MsBuild script. Not to mention the UI for both the console and GUI are much prettier these days. You can grab the bits for Gallio here on google code.

Icarus Gallio-Icarus

Echo Gallio-Echo

NBehave, has been working hard along side of the guys at MbUnit to work together in creating a better test environment, however since they still have plenty to do, they put up a blog post, using the current bits of NBehave , in order to create specifications using NUnit, which can also be applied to other Xunit frameworks. Much of BDD has to do with DSL (domain specific language) and the wording structure and thought process, more than the inner workings of code. This can be demonstrated in that blog post, changing the attributes, which will decorate the same way you would in a unit test, but give the developer a new meaning.

However, words like “context” and “specification” used in the example from the nbehave update can be blah and since people that are most familiar with BDD are probably rails developers using Rspec. So lets take this a step further, using NBehave, Gallio and MbUnit and product a spec. (Plus they tied that MbUnitSpecBase to Rhino Mock and used underscores in their method names.. grrrrr, don’t tightly couple frameworks). C# isn’t ruby.

//-----------------------------------------------------------------------
// <copyright file="Copyright.cs" author="Michael Herndon">
//     Copyright (c) Michael Herndon.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Amplify
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using Gallio.Framework;
    using MbUnit.Framework;
    using NBehave.Spec.MbUnit;
    using NBehave.Specs;
    using NBehave;

    using It = MbUnit.Framework.TestAttribute;
    using Describe = MbUnit.Framework.CategoryAttribute;
    using InContext = MbUnit.Framework.DescriptionAttribute;
    using Should = MbUnit.Framework.DescriptionAttribute;
    #endregion

    [
        Author("Michael Herndon", "mherndon@opensourceconnections.com", "opensourceconnections.com"),
        Describe("ApplicationContext Specification"),
        InContext("using the context for managing application wide values and configuration")
    ]
    public class ApplicationContextObject : Spec
    }

        [It, Should("lazy load or create the AmplifyConfiguration.")]
        public void GetAndValidationApplicationSection()
        {
            ApplicationContext.AmplifyConfiguration.ShouldNotBeNull();
            ApplicationContext.AmplifyConfiguration.ApplicationName.ShouldBe("Amplify.Net Application");
            ApplicationContext.AmplifyConfiguration.ConnectionStringName.ShouldBe("development");

            ApplicationContext.ApplicationName.ShouldBe("Amplify.Net Application");
            ApplicationContext.ConnectionStringName.ShouldBe("development");
        }
    }
}

ahhh yes, this looks more like familiar territory without trying to make C# into ruby using underscores in method names, while staying true to something like rspec. Of course you could easily just do this with MbUnit and creating your own extension methods and not use NBehave. Now you can even make multiple classes for different contexts (uses of something) for the same specification by using the Describe(CategoryAttribute), similar to how rspec does. So building off of NBehave’s very cool idea of using what we already have, we can now use specifications in a cool neutral testing platform of Gallio, and tying that into our continuous integration setup, leaving the door open later to come back and generate nice reports from the above code.

So of course now, i’m now using this type of testing setup for amplify and its made unit testing enjoyable.




More blog articles:


Let's do a project together!

We provide tailored search, discovery and personalization solutions using Solr and Elasticsearch. Learn more about our service offerings