The documentation on SpecsFor is sorely lacking.  Me (and another volunteer!) are working to fix that.  This is part of a series of posts about SpecsFor, which will eventually make its way in to the official docs.

[more]

REMINDER: We are not worrying about TDD yet.  We’ll get there, but for now, I ask that you suppress your urge to scream at the indignity of “test after” development. 

In Part 1, we covered how to organize and names our specs, and we created the skeleton for specs around an Automobile class.  Here’s the code for Automobile for reference:

public class Automobile
{
    public AutomobileState State { get; set; }

    public StartResult Start()
    {
        bool successful = false;

        if (State == AutomobileState.Stopped)
        {
            State = AutomobileState.Running;
            successful = true;
        }

        return new StartResult
        {
            Successful = successful,
            State = State
        };
    }
}

Let’s implement our scenario.  First, let’s handle the given: “Given the automobile is stopped, when we start it, then the car starts.”  SpecsFor provides a virtual Given method you can override to establish context, so let’s do that.  In our Given, let’s make sure our car is stopped.  Remember that SUT stands for “System Under Test,” and SpecsFor has helped us out by populating it with an instance of Automobile for us automatically:

protected override void Given()
{
    SUT.State = AutomobileState.Stopped;
}

Next, let’s focus on the when, which we’ll implement in SpecsFor virtual “When” method. "Given the automobile is stopped, when we start it, then the car starts."

private StartResult _result;
protected override void When()
{
    _result = SUT.Start();
}

Notice that we also declared a field and captured the return value of the Start method in that field.  That enables us to write some specs against it! 

Now let’s tackle the "then" part of our spec.  There’s nothing to override here.  You just create a normal NUnit test case.  "Given the automobile is stopped, when we start it, then the car starts."

[Test]
public void then_the_engine_is_started()
{
    SUT.State.ShouldEqual(AutomobileState.Running);
}

Cool!  Our first spec!  Typically we’d want to go ahead and run that spec, but we don’t have a test runner yet, so let’s write another spec instead, and make sure the result looks like what we’d expect:

[Test]
public void then_the_result_is_successful()
{
    _result.Successful.ShouldBeTrue();
    _result.State.ShouldEqual(AutomobileState.Running);
}

Alright, so there’s our spec, but there’s a subtle problem with it.  If our test fails because the Successful property is false instead of true, our test will stop, and we won’t know whether or not State was populated correctly.  We could split this spec, but SpecsFor has a nice solution to this problem, which we’ll apply next… once we can run our tests.

And that is going to be the topic of the next post in this series.  🙂