Create and Populate Objects in SpecFlow Scenarios

SpecFlow is definitely my favorite new tool for 2012. If you haven’t checked it out yet, you should. If you’ve checked it out and still don’t get it, come talk to me. I love writing scenarios using business language to help guide my test-driven development. The integration-level tests are proving to be an awesome supplement to more traditional isolated unit tests.

Sometimes it’s hard to come up with a good scenario step because you need to specify several details. Don’t worry, though–SpecFlow’s got ya covered with its Assist Helpers. Let’s say I’m working on some code that has a configuration object that contains my application’s settings. When I’m writing a feature scenario, I might want to provide these settings. I can do just that by putting the details into a table in my scenario.

Configuration.cs

public class Configuration
{
    public string OutputDir { get; set; }
    public bool Enabled { get; set; }
}

Feature1.feature

Scenario: CreateInstance demo
    Given I have the following configuration
        | output dir | enabled |
        | c:\blah    | true    |
    When I do something
    Then what I expected to happen happened

In my step definition, I can import the TechTalk.SpecFlow.Assist namespace to use Assist Helpers like the CreateInstance<T> extension method. When called on a table, CreateInstance will match columns to properties to create and populate an object. Here’s how I use it with the above example:

[Given(@"I have the following configuration")]
public void GivenIHaveTheFollowingConfiguration(Table table)
{
    var config = table.CreateInstance();
}

When creating the object, case-sensitivity and whitespace are ignored, allowing you to create a human-friendly table of your object’s property values. You can also use a vertical table with properties listed as rows. This table will produce the same result as above:

Scenario: CreateInstance demo
    Given I have the following configuration
        | Field      | Value   |
        | output dir | c:\blah |
        | enabled    | true    |
    When I do something
    Then what I expected to happen happened

This technique allows you to create complex objects without having to write any code. You can create highly re-usable steps that rely on the scenario author to provide necessary details in the scenario itself. Simply awesome!

Advertisement

Author: Adam Prescott

I'm enthusiastic and passionate about creating intuitive, great-looking software. I strive to find the simplest solutions to complex problems, and I embrace agile principles and test-driven development.

4 thoughts on “Create and Populate Objects in SpecFlow Scenarios”

  1. Great post. I have recently also written an article as part of the “Specflow Cookbook” project I am involved with dealing with not only how objects can be created using tables, but also how it would be possible to satisfy foreign key constrains between objects created in seperate specflow tables without having to write any custom step logic.

    I would be very interested to hear your thoughts.

    http://specflowcookbook.com/chapters/linking-table-rows/

    Here I suggest using a convention which allows you to use the specflow table headers to indicate where the linked items come from, how to identify which ones you want, and then use the content of the rows to provide the data to “lookup” in the foreign tables.

    For instance:

    Scenario: Letters to Santa appear in the emailers outbox

    Given the following “Children” exist
    | First Name | Last Name | Age |
    | Noah | Smith | 6 |
    | Oliver | Thompson | 3 |

    And the following “Gifts” exist
    | Child from Children | Type | Colour |
    | Last Name is Smith | Lego Set | |
    | Last Name is Thompson | Robot | Red |
    | Last Name is Thompson | Bike | Blue |

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: