简体   繁体   中英

How to apply a default value into specflow step definition table even if the user does not provide the column name

How to apply a default value into the specflow step definition table even if the user does not provide the column name?

Example: This is my feature file

@regression @add-a-new-cat
Feature: Add a new cat
  As a User
  I should be able to add a cat

  # Vocabulary:
  # User: An authorized application user

  @positive @smoke-test
  Scenario: Add a new cat
    Given the User is authorized to add a new cat
    When the User adds new cat
    | CatName | Age | Breed  |
    | Kitty   | 5   | Indian |
    | Lucy   | 5   | Persian |
    Then the cat is added successfully

Ideal case step definition:

[When(@"the User adds new cat")]
public async void WhenTheUserAddsNewCatEndpointAsync(Table table)
{
    var addCats = table.CreateSet<CatDetails>();
    var request = new RestRequest("cats");
    request.AddBody(addCats);
    restResponse = await restSharpRetryDriver.restClient.ExecutePostAsync(request);
}

Now my requirement is - how can I pass a default value to a data table column if the user does not pass all the columns in the datatable.

Example:

@regression @add-a-new-cat
Feature: Add a new cat
  As a User
  I should be able to add a cat

  # Vocabulary:
  # User: An authorized application user

  @positive @smoke-test
  Scenario: Add a new cat
    Given the User is authorized to add a new cat
    When the User adds new cat
    | CatName | Age |
    | Kitty   | 5   |
    | Lucy    | 5   |
    Then the cat is added successfully

Now the step definition should assign a default value for the "Breed" Column. A solution that I'm aware of is:

[When(@"the User adds new cat")]
public async void WhenTheUserAddsNewCatEndpointAsync(Table table)
{
    var addCats = table.CreateSet<CatDetails>();
    foreach (var row in addCats)
    {
        if (row.Breed == null)
        {
           row.Breed = "persian"; // Assigning a default value, if the column name is not passed from the feature file
        }
    }
    var request = new RestRequest("cats");
    request.AddBody(addCats);
    restResponse = await restSharpRetryDriver.restClient.ExecutePostAsync(request);
}

OR

public class AddCatSteps
{
    public class CatDetails
    {
        [TableAliases("Name", "CatName")]
        public string Name { get; set; }
        public int Age { get; set; }
        //public string Breed { get; set; }
        string _breed;
        public string Breed
        {
            get
            {
                if (_breed == null)
                {
                    return "newBreed";
                }
                else
                {
                    return _breed;
                }
            }
            set
            {
                _breed = value;
            }
        }
    }

    [When(@"the User adds new cat")]
    public async void WhenTheUserAddsNewCatEndpointAsync(Table table)
    {
        var addCats = table.CreateSet<CatDetails>();
        var request = new RestRequest("cats");
        request.AddBody(addCats);
        restResponse = await restSharpRetryDriver.restClient.ExecutePostAsync(request);
    }
}

But this does not seem like the best solution, especially if many columns are involved. Can anyone suggest a better solution?

Thanks in advance.

If using a recent enough version of C#, simply set the default value after the definition of the property:

public class CatDetails
{
    public string Breed { get; set; } = "newBreed";

Or, simply set this in the default constructor for CatDetails:

public class CatDetails
{
    public string Breed { get; set; }

    public CatDetails()
    {
        Breed = "newBreed";
    }

The table.CreateSet<T>() and table.CreateInstance<T>() methods call the default constructor of T .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM