Specification test patterns

I’m fan of specification style testing. I’ve used mspec on my own projects and have been really happy with it. I would use it at work too, however, most developers I have/are working with have never heard of it let along used it. I would say all these developers have used a xUnit like test framework and if I was to guess which one it would be NUnit. It would be unreasonable of me to force everyone to switch to mspec just because I like it. Also, there is a slight learning curve – when developers already complain that writing tests slow them down, I don’t want them to slow them down further. (There are other reasons too, but I don’t want to go into those.)

So how can we write specification style tests using the tools we already have? Simple, use one test class per test:

public class When_I_initialize_People_with_text
{
    private People people;

    public When_I_initialize_People_with_text()
    {
        people = new People { "{\"firstName\":\"John\", 
                                \"lastName\":\"Smith\"}" };
    }

    [Fact]
    public void It_should_contain_expected_number_of_items()
    {
        people.Count().Should().Be(1);
    }

    [Fact]
    public void It_should_contain_expected_person()
    {
        people.First().ShouldBeEquivalentTo(
            new Person("John", "Smith"));
    }
}

I’m using xUnit 2 in the example above but that’s because I prefer it over NUnit. With xUnit there is just one attribute to remember and the setup/teardown is much simpler.

The test class does one thing – its written on the tin. The assertions, too, are clear. You might not approve of the underscores, but I think its easier to read than using PascalCase.

This pattern is fine for most cases, but what if your setup/teardown parts are slow, for example, seeding a database with some test data. You have to use class fixtures.

public class When_I_initialize_People_with_text_that_includes_invalid_data
    : IClassFixture
{
    public class Context : Context
    {
        public Context()
        {
            SUT = new People { 
                "{\"firstName\":\"John\", " +
                "\"lastName\":\"Smith\"}",
                "{\"member\":\"John\", " +
                "\"another_member\":\"Smith\"}" 
            };
        }
    }

    private People people;

    public When_I_initialize_People_with_text_that_includes_invalid_data(Context context)
    {
        people = context.SUT;
    }

    [Fact]
    public void It_should_contain_expected_number_of_items()
    {
        people.Count().Should().Be(1);
    }

    [Fact]
    public void It_should_contain_expected_person()
    {
        people.First().ShouldBeEquivalentTo(
            new Person("John", "Smith"));
    }
}

Its not quite as readable, but its not bad. (There is an alternative – I’ll save it for a future post.)

Code samples can be found here: Specification Test Patterns