Saturday, February 27, 2010

Behaviors with MSpec

In my previous posts, I showed the syntax for context/specifications using Machine.Specifications (or MSpec for short) and how to use an auto mocking container in conjunction with this excellent Behavior-Driven Development (BDD) framework. For this post, I want to show you one of the nice features of MSpec called behaviors.

Suppose we have to create some sort of specification that validates the format of an e-mail address. We typically use some regular expression in order to ensure that a specified e-mail address is properly formatted.

public class EmailSpecification
{
    private const String EmailRegexPattern = @".. SOME_REGEX_PATTERN ...";

    public Boolean IsSatisfiedBy(String candidate)
    {
        var regex = new Regex(EmailRegexPattern);
        return regex.IsMatch(candidate);
    }
}

I guess this is pretty common and straightforward. One way to provide some unit tests for this particular piece of code is to check a whole number of e-mail addresses that either pass or fail the specification. The following example shows only a couple of scenarios:

[TestFixture]
public class When_validating_an_email
    : ContextSpecification<EmailSpecification>
{
    protected override EmailSpecification Create_subject_under_test()
    {
        return new EmailSpecification();
    }

    [Test]
    public void ShouldBeSatisfied()
    {
        Assert.That(SUT.IsSatisfiedBy("one2@three.com"));
        Assert.That(SUT.IsSatisfiedBy("one@two3.com"));
    }

    [Test]
    public void ShouldNotBeSatisfied()
    {
        Assert.That(SUT.IsSatisfiedBy("one_two.com"), Is.False);
        Assert.That(SUT.IsSatisfiedBy("one_two@"), Is.False);
    }
}

A slightly more concise approach for these kind of unit tests can be accomplished by utilizing a feature of any decent unit test framework called row tests. With this approach we can, at the very least, reduce the number of asserts we have to write for each unit test. 

[TestFixture]
public class When_validating_an_email__approach_2
    : ContextSpecification<EmailSpecification>
{
    protected override EmailSpecification Create_subject_under_test()
    {
        return new EmailSpecification();
    }

    [RowTest]
    [Row("one2@three.com")]
    [Row("one@two3.com")]
    public void ShouldBeSatisfied(String email)
    {
        Assert.That(SUT.IsSatisfiedBy(email));
    }

    [RowTest]
    [Row("one_two.com")]
    [Row("one_two@")]
    public void ShouldNotBeSatisfied(String email)
    {
        Assert.That(SUT.IsSatisfiedBy(email), Is.False);
    }
}

Notice that I explicitly called both of these approaches unit tests as they don’t have much to do with BDD in my opinion. I’m not saying that using regular unit tests is a bad thing, but with  behavior-driven development context is king. So these unit tests are perfect examples of ‘context betrayal’ when following the BDD approach.

Lets see what MSpec can bring to the table for these kind of scenarios:

[Subject(typeof(EmailSpecification), "is satisfied")]
public class when_validating_an_email_address_with_a_number_in_the_local_part
    : email_specification_specs
{
    Establish context = () =>
        EmailAddress = "one2@three.com";

    Behaves_like<SatisfiedSpecificationBehavior> a_satisfied_specification;
}

[Subject(typeof(EmailSpecification), "is satisfied")]
public class when_validating_an_email_address_with_a_number_in_the_domain_name
    : email_specification_specs
{
    Establish context = () =>
        EmailAddress = "one@two3.com";

    Behaves_like<SatisfiedSpecificationBehavior> a_satisfied_specification;
}

[Subject(typeof(EmailSpecification), "is satisfied")]
public class when_validating_an_email_address_without_an_At_sign
    : email_specification_specs
{
    Establish context = () =>
        EmailAddress = "one_two.com";

    Behaves_like<UnsatisfiedSpecificationBehavior> an_unsatisfied_specification;
}

[Subject(typeof(EmailSpecification), "is satisfied")]
public class when_validating_an_email_address_without_a_domain
    : email_specification_specs
{
    Establish context = () =>
        EmailAddress = "one_two@";

    Behaves_like<UnsatisfiedSpecificationBehavior> an_unsatisfied_specification;
}

In order to escape ‘context betrayal’, we’ve split up every context into a separate context/specification. In order to reduce the amount of effort caused by duplicate code, we stripped the context setup to the bare minimum (just a particular e-mail address in this case). The observations are isolated into MSpec behaviors which provides a very readable description of their outcome. Lets take a look at what is needed in order to get these behaviors to work.

But first lets take at look at the abstract base class that we’ve used for the context/specifications we’ve just shown.

public abstract class email_specification_specs
{
    Establish context = () =>
    {
        SUT = new EmailSpecification();
    };

    Because of = () =>
        Result = SUT.IsSatisfiedBy(EmailAddress);

    protected static Boolean Result;
    protected static String EmailAddress { get; set; }
    protected static EmailSpecification SUT { get; set; }
}

We abstracted as much as possible into this base class in order to remove duplication in the context/specifications. The creation of the subject-under-test and the calling of its IsSatisfiedBy method, but the important one is the declaration of the Result field. This field contains the outcome of the IsSatisfiedBy method. Finally, lets have a look at the behaviors themselves:

[Behaviors]
public class SatisfiedSpecificationBehavior
{
    protected static Boolean Result;
    
    It should_satisfy_the_specification = () =>
        Result.ShouldBeTrue();
}

[Behaviors]
public class UnsatisfiedSpecificationBehavior
{
    protected static Boolean Result;

    It should_not_satisfy_the_specification = () =>
        Result.ShouldBeFalse();
}

In order to create an MSpec behavior, we just have to create a separate class that we decorate with the Behaviors attribute. Also notice that we have the same declaration of the Result field. MSpec ensures that this field gets initialized with the value of the other Result field that is set in the base class of the context/specifications. Note that you don’t necessarily need to put this field in a base class. You can have that field in every context/specification if you’d like (not sure why) as long as the names match with the fields used in the defined behaviors.

I personally like the way how the MSpec contributors tried to solve testing the same logic with different input patterns and the syntax they provided to back this up.  

Tuesday, February 23, 2010

MSpec and Auto Mocking

In my previous post, I explained how to get started with Machine.Specifications (or MSpec for short) and showed you how the syntax for context/specifications looks like when using this BDD framework. For this post, I want to show you how to use an auto mocking container (we’ll be using the one provided by StructureMap off course).

We’ll use the same example as the one used in the previous post, but now we’ll deal with the message handler that makes a particular customer preferred.

//
// Subject under test
//
public class MakeCustomerPreferredMessageHandler
{
    private readonly ICustomerRepository<ICanMakeCustomerPreferred> _repository;

    public MakeCustomerPreferredMessageHandler(
        ICustomerRepository<ICanMakeCustomerPreferred> repository)
    {
        _repository = repository;
    }

    public void Handle(MakeCustomerPreferredMessage message)
    {
        var customer = _repository.Get(message.CustomerId);
        if(null == customer)
            throw new InvalidOperationException(
                "No customer for specified identifier");
        
        customer.MakePreferred();
        _repository.Save(customer);
    }
}

The Customer class implements a ‘role interface’ called ICanMakeCustomerPreferred. We retrieve a customer from the repository and make it preferred. We throw an exception in case the customer cannot be found in the data store.

Here are the context/specifications for this easy example:

[Subject("Making a customer preferred")]
public class when_making_a_customer_preferred
    : context_specification<MakeCustomerPreferredMessageHandler>
{
    Establish context = () =>
    {
        _message = new MakeCustomerPreferredMessage { CustomerId = 6412 };

        Repository.Stub(repository => repository.Get(_message.CustomerId))
            .Return(Customer);
    };

    Because of = () => 
        SUT.Handle(_message);
    
    It should_mark_the_customer_as_preferred = () =>
        Customer.AssertWasCalled(customer => customer.MakePreferred());

    It should_save_the_customer_in_the_repository = () =>
        Repository.AssertWasCalled(repository => repository.Save(Customer));

    private static ICanMakeCustomerPreferred Customer
    {
        get { return Dependency<ICanMakeCustomerPreferred>(); }
    }

    private static ICustomerRepository<ICanMakeCustomerPreferred> Repository
    {
        get { return Dependency<ICustomerRepository<ICanMakeCustomerPreferred>>(); }
    }

    private static MakeCustomerPreferredMessage _message;
}

[Subject("Making a customer preferred")]
public class when_making_an_unexisting_customer_preferred
    : context_specification<MakeCustomerPreferredMessageHandler>
{
    Establish context = () =>   
    {
        _message = new MakeCustomerPreferredMessage() { CustomerId = 61544 };

        Dependency<ICustomerRepository<ICanMakeCustomerPreferred>>()
            .Stub(repository => repository.Get(_message.CustomerId))
            .Return(null);
    };

    Because of = () =>
        _resultingException = Catch.Exception(() => SUT.Handle(_message));

    It should_result_in_an_error = () =>
        _resultingException.ShouldBeOfType<InvalidOperationException>();

    private static MakeCustomerPreferredMessage _message;
    private static Exception _resultingException;
}

I want to point out that all fields and properties are made static. This is needed so that the anonymous methods can access them. I’m also using a base class for these specifications which I’ll show next. This base class uses an auto mocking container for providing the requested mocks and stubs through the Dependency and Stub methods.

public abstract class context_specification<TSubjectUnderTest>
    where TSubjectUnderTest : class
{
    private static IAutoMockingContainer<TSubjectUnderTest> _autoMockingContainer;
    protected static TSubjectUnderTest SUT { get; set; }

    Establish context = () =>
    {
        _autoMockingContainer = new StructureMapAMC<TSubjectUnderTest>();
        SUT = _autoMockingContainer.Create();     
    };
    
    Cleanup stuff = () => 
    {
        SUT = null;
        _autoMockingContainer = null;
    };

    protected static TDependency Dependency<TDependency>()
        where TDependency : class
    {
        return _autoMockingContainer.GetMock<TDependency>();
    }

    protected static TStub Stub<TStub>()
        where TStub : class
    {
        return _autoMockingContainer.GetStub<TStub>();
    }
}

public interface IAutoMockingContainer<TSubject>
    where TSubject : class
{
    TSubject Create();
    TMock GetMock<TMock>() where TMock : class;
    TStub GetStub<TStub>() where TStub : class;
}

public class StructureMapAMC<TSubject> 
    : IAutoMockingContainer<TSubject>
    where TSubject : class
{
    private readonly RhinoAutoMocker<TSubject> _rhinoAutoMocker;

    public StructureMapAMC()
    {
        _rhinoAutoMocker = 
            new RhinoAutoMocker<TSubject>(MockMode.AAA);
    }

    public TSubject Create()
    {
        return _rhinoAutoMocker.ClassUnderTest;
    }

    public TMock GetMock<TMock>() 
        where TMock : class
    {
        return GetDependency<TMock>();
    }

    public TStub GetStub<TStub>() 
        where TStub : class
    {
        return GetDependency<TStub>();
    }

    private TDependency GetDependency<TDependency>() 
        where TDependency : class
    {
        return _rhinoAutoMocker.Get<TDependency>();
    }
}

Notice that I’m using the Establish and Cleanup delegates in the context_specification base class. This doesn’t prevent that these can be used again in derived context/specifications. MSpec ensures that the anonymous methods are called in the right order. This means that the Establish method of the base class is called before the Establish method of the derived context/specifications.    

Absolutely no rocket science here, but I figured it might come in handy when you need it. For the next post I’ll try to demonstrate how to deal with reusable behaviors.

Friday, February 19, 2010

Getting Started With Machine.Specifications (MSpec)

Its been a while since I evaluated and evolved my approach to BDD. The way I’ve been doing BDD up until now is described in this blog post which goes way back to 2008. Everyone has kind of their own style nowadays. Below you can find the code of two context/specifications for a method named MakePreferred on a Customer class. This simple example clarifies the style that I’ve been following up until now.

[TestFixture]
public class When_making_a_regular_customer_preferred
    : ContextSpecification<Customer>
{
    protected override Customer Create_subject_under_test()
    {
        return new Customer(new[] { _order });
    }

    protected override void Establish_context()
    {
        _order = new Order(new[] { new OrderItem(12), 
                                   new OrderItem(16) });
                                   
        _totalAmountWithoutDiscount = _order.TotalAmount;
    }

    protected override void Because()
    {
        SUT.MakePreferred();
    }

    [Test]
    public void Then_the_customer_should_be_marked_as_preferred()
    {
        SUT.IsPreferred.ShouldBeTrue();
    }

    [Test]
    public void Then_a_ten_percent_discount_should_be_applied_to_all_outstanding_orders()
    {
        _order.TotalAmount.ShouldBeEqualTo(
            _totalAmountWithoutDiscount * 0.9);
    }

    private Order _order;
    private Double _totalAmountWithoutDiscount;
}

[TestFixture]
public class When_making_a_preferred_customer_preferred
    : ContextSpecification<Customer>
{
    protected override Customer Create_subject_under_test()
    {
        var customer = new Customer(new[] { _order });
        customer.MakePreferred();
        return customer;
    }

    protected override void Establish_context()
    {
        _order = new Order(new[] { new OrderItem(12), 
                                   new OrderItem(16) });
        _totalAmountWithoutDiscount = _order.TotalAmount;
    }

    protected override void Because()
    {
        SUT.MakePreferred();
    }

    [Test]
    public void Then_no_additional_discount_should_be_applied_to_the_outstanding_orders()
    {
        _order.TotalAmount.ShouldNotBeEqualTo(
            _totalAmountWithoutDiscount * 0.81);
    }

    private Order _order;
    private Double _totalAmountWithoutDiscount;
}

//
// Subject under test
//
public class Customer
{
    private readonly List<Order> _orders;
    public Boolean IsPreferred { get; private set; }

    public Customer(IEnumerable<Order> orders)
    {
        _orders = new List<Order>(orders);
    }

    public void MakePreferred()
    {
        if(IsPreferred)    
            return;
    
        IsPreferred = true;
        _orders.ForEach(order => order.ApplyDiscount(10));
    }
}

The bottom line of this example is that preferred customers get a 10 percent discount. Customers that are already preferred do not get an additional discount or otherwise we’re out of business ;-).

I’ve been pretty happy with this approach so far, although sometimes there were some quirks associated with this. So it was time for me to look beyond the horizon again, trying to look for ways to improve.

Machine.Specifications or MSpec for short is something that has been on my ‘cool-things-to-learn-list’ for quite some time now. As you will see later in this post, the syntax is a bit different as one would come to expect from a context/specification framework that targets the C# programming language. Its seems to be heavily inspired by Scott Bellware’s SpecUnit framework and RSpec.

Lets see how to set things up first.

The most obvious starting point is downloading the bits and bytes. You can grab the source code from GitHub and build it or you can wuss out like I did and get the latest build from the TeamCity.CodeBetter.com builder server (you can log on as a guest and search the artifacts for a latest build). 

When you’re heavily addicted to TestDriven.NET like I am, then its possible to keep using this wonderful Visual Studio add-in for running MSpec context/specifications. Just create a directory named Machine.Specifications in {$Program_Files}\TestDriven.NET 2.0 and copy the following files:

  • Machine.Specifications.dll
  • Machine.Specifications.TDNetRunner.dll
  • InstallTDNetRunner.bat
    Run the InstallTDNetRunner.bat file and you’re able to run all MSpec context/specifications using TestDriven.NET.

I also strongly encourage you to install the plugin for the Resharper test runner (if only to prevent some Resharper warnings later on). First step is to add a directory named Plugins to the Bin directory of Resharper ({$Program_Files}\JetBrains\ReSharper\v4.5\Bin\). Then create a directory named Machine.Specifications in the Plugins directory you just created and copy the following files:

  • Machine.Specifications.dll
  • Machine.Specifications.ReSharperRunner.4.5.dll
  • InstallResharperRunner.4.5.bat

Run the InstallResharperRunner.4.5.bat file and you’re also able to run MSpec context/specifications using the Resharper test runner.

I’m not going to put this off any longer. Lets look at the code of the context/specifications shown earlier but completely revamped using the MSpec syntax:

[Subject("Making a customer preferred")]
public class when_a_regular_customer_is_made_preferred 
{
    Establish context = () =>
    {
        _order = new Order(new[] { new OrderItem(12), 
                                   new OrderItem(16) });
        _totalAmountWithoutDiscount = _order.TotalAmount;

        SUT = new Customer(new[] { _order });
    };

    Because of = () => 
        SUT.MakePreferred();

    It should_mark_the_customer_as_preferred = () =>
        SUT.IsPreferred.ShouldBeTrue();
        
    It should_apply_a_ten_percent_discount_to_all_outstanding_orders = () =>
        _order.TotalAmount.ShouldEqual(_totalAmountWithoutDiscount * 0.9);      

    private static Customer SUT;
    
    private static Order _order;
    private static Double _totalAmountWithoutDiscount;
}

[Subject("Making a customer preferred")]
public class when_a_preferred_customer_is_made_preferred
{
    Establish context = () =>
    {
        _order = new Order(new[] { new OrderItem(12), 
                                   new OrderItem(16) });
        _totalAmountWithoutDiscount = _order.TotalAmount;

        SUT = new Customer(new[] { _order });
        SUT.MakePreferred();
    };

    Because of = () =>
        SUT.MakePreferred();

    It should_apply_no_additional_discount_to_the_outstanding_orders = () => 
        _order.TotalAmount.ShouldNotEqual(_totalAmountWithoutDiscount * 0.81);

    private static Customer SUT;

    private static Order _order;
    private static Double _totalAmountWithoutDiscount;
}

I warned you about the syntax, didn’t I :-). It only took me a couple of seconds to get used to this syntax but now I’m completely hooked. Instead of using methods and attributes, MSpec utilizes delegates and anonymous methods. But there’s more.

When using NUnit for writing context/ specifications, the Establish_context and Because methods of the example shown earlier is executed before every observation (test). With MSpec, the Establish and Because anonymous methods are executed only once for every context no matter how many observations a particular context class contains. Big difference? Well, at first glance not but on second hand it does make selling out on the context a bit more difficult as it will probably blow up in your face sooner than later. You can force MSpec to execute the Establish and Because anonymous methods before every observation by applying the SetupForEachSpecification attribute to the context class, but I strongly encourage you to stay away from that unless absolutely needed.

Also notice that the fields in the contexts are now all static. This is needed so that the anonymous methods can access those.     

Running these context/specifications using TestDriven.NET yields the following output in the output window of Visual Studio:

Making a customer preferred, when a regular customer is made preferred
» should mark the customer as preferred
» should apply a ten percent discount to all outstanding orders

Making a customer preferred, when a preferred customer is made preferred
» should apply no additional discount to the outstanding orders

What’s not to like? Well, the only downside so far is that Resharper was giving me some warnings about classes and fields not being used etc. … . Many of those warnings disappeared by registering the MSpec plugin for the Resharper test runner as I explained earlier.

So far, so good. I’ve got two more posts coming up on MSpec, so stay tuned.

Saturday, February 13, 2010

Is NoSQL Finally Going Mainstream?

Its been a while since I enjoyed my adventures with CouchDB. I sure wish I could have some extra time to pick this up again, but getting some sleep at night is nice too once in a while. I noticed that OO databases and document/key-value stores are getting more and more traction lately and I must say that its about time.

Rob Conery hits the nail right on the head in his post on Reporting in NoSQL.

Put as gently as I can – relational systems are an answer to a problem that we faced 30 years ago. What you’re doing now is nothing other than compensating for a lack of imagination from the platform developers. Think about it – we code using Object Oriented approaches, we store those objects in a relational system.

What we should all learn in this industry is to stop assuming that a relational database is the default option for storing the data of every solution we build. This is what we have been doing for a long time and its pure madness, plain and simple.

RDBMS don’t fit for holding your application’s data, and they don’t fit for reporting. They’re a solution for a problem that doesn’t exist anymore. Time to kick them to the curb.

The most typical setup you see is a single relational database that is used for both storing the data of an application as well as reporting from this data. The relational schema usually sits between normalized and denormalized tables, which means having a compromise for both needs. You can get away with this for small to medium-sized applications, but when you start working on mission-critical solutions with higher volumes, this compromise isn’t going to cut it anymore. This is why Greg Young, Udi Dahan and Mark Nijhof amongst others are advocating command query separation. For these kind of solutions, you want to have the best option for handling commands, which could be an OO database or a document/key-value store (with or without event-sourcing) and for reporting you’d want the best option available as well like an OLAP system. What I’m describing here is just the elevator pitch, so if you want to learn more about this then do checkout the resources that these gentlemen mentioned above have already put on their blogs.

I hope that one day we realize that a relational database was just a means for optimizing file storage, which is hardly a need anymore these days. We shouldn’t be struggling with how to solve the impedance mismatch between relational databases and OO programming in any kind of application. The one thing we should care about is how to provide solid and clean solutions to our businesses without having to worry about tables and those zealots with their holy database schemas. Just store the objects you want and worry about other things like the so-called ‘ilities’ and being able to respond to business needs in a timely manner. 

Friday, February 05, 2010

Integrating ELMAH for a WCF Service

Peter Cosemans, who is one of my colleagues, found a nice way to integrate ELMAH for a WCF service. ELMAH is an error logging facility for logging unhandled exceptions particularly focused on ASP.NET web applications. There are plenty of sources out there, like this blog post by Scott Hanselman, that describe how to get ELMAH up and running for an ASP.NET web application.

In order to get it working for WCF, you need to provide a custom error handler by implementing the IErrorHandler interface:

public class ElmahErrorHandler : IErrorHandler
{
    public void ProvideFault(Exception error, MessageVersion version, 
                             ref Message fault)
    {
        var dummyRequest = 
            new SimpleWorkerRequest("dummy", "", new StringWriter());
        var context = new HttpContext(dummyRequest);
        
        var elmahLogger = Elmah.ErrorLog.GetDefault(context);
        elmahLogger.Log(new Elmah.Error(error));    
    }

    public Boolean HandleError(Exception error)
    {
        SDExceptionHandler.DoHandle(error);
        return true;
    }
}

This error handler needs to be added to the stack of error handlers. You can do this in a couple of ways, for example by providing a custom attribute that implements IServiceBehavior and then applying this attribute to your service class.

Next you need to add some configuration to your web.config and your all good to go:

<system.web>
    <httpHandlers>
        <add verb="POST,GET,HEAD" 
             path="MyService.Elmah.axd" 
             type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
</system.web>

<elmah>
    <errorLog type="Elmah.XmlFileErrorLog, Elmah" 
              logPath="C:\MyServiceLog\"/>
</elmah>

What’s nice about this approach is that you don’t need to run the WCF service in ASP.NET compatibility mode, which is a major bonus.

Hope this helps