Question

I'm trying out the specFlow assist and not sure how would one create class property from table. Imagine I have this class:

public class Tracking 
{
    public string Category { get; set; }
}

public class ODARequest
{
    public string Title { get; set; }
    public string Name { get; set; }
    public Tracking Tracking { get; set; }
}

My Given scenario is next:

Scenario: Successfully create an account
Given I have entered the following data into the ODA form:
    | Field                  | Value            |
    | Title                  | Mr               |
    | Name                   | Andy             |
    | Tracking Category      | MDA              |


public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(Table table)
{
    var request = table.CreateInstance<ODARequest>();
}

The Tracking property will not be populated. Anyone know how to describe Tracking.Category in the table for this situation?

Was it helpful?

Solution 2

I've been hitting this problem and been thinking how to do it with a single step.

Scenario: Successfully create an account
Given I have entered the following data into the ODA form:
    |Title | Name | Category|
    | Mr   | Andy | MDA     |

public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(Table table)
{
    var request = table.CreateInstance<ODARequest>();
    request.Tracking = table.CreateInstance<Tracking>();
}

How it works: You may call "CreateInstance" for each complex property you have so specflow will create you an instance. So you can have a single table with properties from different types.

By doing so you won't need a different step and the need of sharing data between the steps.

The drawback is that you may end up with a huge table if your class has a lot of properties with different types.

Note: As @Alex M commented it there is a risk when the classes are having a property with same name. What will happen actually is that both instances will get the same value due to the property name match on both classes.

OTHER TIPS

I haven't been able to find a way of getting specflow to map "CreateInstance" to non-standard data types properties.

However, in this case you could at least use a StepArgumentTransformation as follows:

    [Given(@"I have entered the following data into the ODA form:")]
    public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(ODARequest request)
    {
        Assert.IsNotNull(request.Tracking);
    }

    [StepArgumentTransformation(@".*")]
    public ODARequest StringToTracking(Table input)
    {
        return new ODARequest() { 
            Title = input.Rows.Single(row => row["Title"])["value"],
            Name = input.Rows.Single(row => row["Name"])["value"],
            Tracking = new Tracking() 
                { Category = input.Rows.Single(row => row["Field"] == "Tracking Category")["Value"] }
            };
    }

With a little work you could tidy the stepargumenttransformation up to accept each parameter as optional (rather than having "single()" throw if it is omitted).

I feel like there really ought to be a better way to do this, more like your original suggested code. Hope this is helpful.

Another possibility without modifying the specflow assist itself is to separate the subclass properties into separate Given. Can be as per below example:

Scenario: Successfully create an account
Given I have entered the following data into the ODA form:
| Field                  | Value            |
| Title                  | Mr               |
| Name                   | Andy             |
And the tracking info as:
| Tracking Category      | MDA              |

then my step definitions would be as:

[Given(@"I have entered the following data into the ODA form:")]
public void GivenIHaveEnteredTheFollowingDataIntoTheODAForm(Table table)
{
    var request = table.CreateInstance<ODARequest>();
    ScenarioContext.Current.Set(request, "request");
}
[Given(@"the tracking info as:")]
public void GivenTheTrackingInfoAs(Table table)
{
    var request = ScenarioContext.Current.Get<ODARequest>("request");
    request.TrackingFields = table.CreateInstance<Tracking>();
}

Otherwise the possibility is to contribute to specflow assist development.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top