mosaad
mosaad

Reputation: 2381

How does specflow handle multiple parameters?

As the title says how does specflow handle this

x = AddUp(2, 3)
x = AddUp(5, 7, 8, 2)
x = AddUp(43, 545, 23, 656, 23, 64, 234, 44)

The link I gave is how it is usually done. What i want to know is what should the annotation on the top be?

[Then(@"What should I write here")]
public static void AddUp(params int[] values)
{
   int sum = 0;
   foreach (int value in values)
   {
      sum += value;
   }
   return sum;
}

Upvotes: 4

Views: 13278

Answers (4)

Chris F Carroll
Chris F Carroll

Reputation: 12370

To answer the headline question: SpecFlow parses the regular expressions in the Given spec, so you can do what you need if you're good with regexes. For 2 integer parameters, this would work:

[Given(@"the numbers are (\d+),(\d+)")]
public void GivenTheNumbersAre(int number1, int number2)

However, you have to define a parameter for each capture group. The easiest regex I know for a comma delimited list of integers, with no trailing comma, gets me to:

[Given(@"a list of numbers such as ((\d+,)+(\d+))")]
public void GivenAListOfNumbersSuchAs(string commaDelimitedIntegers, string most, string last)
    {

and throw away the redundant last two parameters and just parse the first parameter:

var numbers = commaDelimitedIntegers
            .Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
            .Select(int.Parse).ToArray();

The only advantage this has over just using .+ for your regex is that intellisense in the feature file can tell you if your parameters don't match the regex.

If you're on the regex learning curve, you can check what you've got with console output:

var console = _scenarioContext.ScenarioContainer.Resolve<ISpecFlowOutputHelper>();
console.WriteLine(commaDelimitedIntegers);
console.WriteLine(most);
console.WriteLine(last.ToString());

Upvotes: 0

Sam Holder
Sam Holder

Reputation: 32946

I don't believe that you can have a binding which uses a param array as the argument type in specflow and have it used automatically. At least I've never used one and have never seen one used.

How would you want to specify this in the feature file? you have given examples of the methods you want to call and the step definition method you want specflow to call, but not how you expect the feature file to read.

My suspicion is that you would want to do something like this

Given I want to add up the numbers 2,5,85,6,78

and ultimately specflow will want to convert this into a string and call a method. You'll have to do the conversion from string to array of numbers yourself, probably using a [StepArgumentTransformation] like this:

[StepArgumentTransformation]
public int[] ConvertToIntArray(string argument)
{
    argument.Split(",").Select(x=>Convert.ToInt32(x)).ToArray();
} 

and you should then be able to define your step definition like so:

[Given(@"I want to add up the numbers (.*)")]
public static void AddUp(params int[] values)
{
    int sum = 0;
    foreach (int value in values)
    {
        sum += value;
    }
    return sum;
}

but honestly at this point you don't need the params bit, int[] will be enough.

Upvotes: 5

mosaad
mosaad

Reputation: 2381

This is the best solution in my opinion:

When I add the following numbers
| Numbers|
| 5      |
| 1      |
| 3      |

And the step

[When(@"I add the following numbers")]
public static void AddUp(Table values)
{
   //addition code
}

Upvotes: 2

tdbeckett
tdbeckett

Reputation: 708

You add parameters by adding single quote marks like this:

[When(@"I perform a simple search on '(.*)'")]
public void WhenIPerformASimpleSearchOn(string searchTerm)
{
    var controller = new CatalogController();
    actionResult = controller.Search(searchTerm);
}

you can use comma seperated lists

When i login to a site
then 'Joe,Bloggs,Peter,Mr,Some street,15' are valid

Also you can use table vales

When I login to a site
then the following values are valid
    | FirstName | LastName | MiddleName | Greeting| Etc    | Etc     |
    | Joe       | Bloggs   | Peter      | Mr      | you get| The Idea|

https://github.com/techtalk/SpecFlow/wiki/Step-Definitions Providing multiple When statements for SpecFlow Scenario Passing arrays of variable in specflow

Upvotes: 3

Related Questions