Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

specflow: - "Ambiguous step definitions found for step" when 1 step has more params than the other

At present we have this step:

[When(@"I set the scenario price for product (.*) to (.*)")]
public void WhenISetTheScenarioPriceForProductPToN(string product, string priceStr)

I wish to add the step:

[When(@"I set the scenario price for product (.*) to (.*) in the (.*) zone")
public void WhenISetTheScenarioPriceInZoneForProductPToN(string product, string priceStr, string zone)

However spec flow gives an “Ambiguous step definitions found for step” error between the two steps.

I have tired:

  [When(@"I set the scenario price for product (.*) to (.*) in the (.*) zone")]
  [When(@"I set the scenario price for product (.*) to (.*)")]
  public void WhenISetTheScenarioPriceInZoneForProductPToN(string product, string priceStr, string zone)

but that fails with a "binding error: Parameter count mismatch!" I was hopeing it would pass null for the 2nd "when".

like image 640
Ian Ringrose Avatar asked Dec 07 '12 12:12

Ian Ringrose


2 Answers

The problem is second your (.*). That can expand to match "xyz in the abc zone". Can you instead match just a single word? i.e. (\w+)

[When(@"I set the scenario price for product (.*) to (\w+)")]

That would then prevent the shorter Regex matching in the abc zone as well.

You can test this by commenting out your longer When attribute and method and debugging to see what matches the shorter one.

Also, you always have to have the same number of Regexes as parameters which is why the combined one doesn't work.


This did not work for me, this is due to a price of "0.99" and "." not being matched by \w. However this works:

[When(@"I set the scenario price for product (.*) to (\S+)")]
public void WhenISetTheScenarioPriceForProductPToN(string product, string priceStr)

as our "test values" don't have spaces in them.

like image 94
AlSki Avatar answered Sep 20 '22 14:09

AlSki


I initially believed this is because the regex at the end of the first step definition:

[When(@"I set the scenario price for product (.*) to (.*)")]

It would capture (or match) the same string that would go into your subsequent definition.

However, it is that and the fact that the two step implementing methods contain ambiguous argument types. I could not reproduce this initially because I used int (as per my comment), but using string you can reproduce this issue as string is ambiguous. Any parameter supplied as an argument in a step definition file can be treated as string.

Change your step methods to the following:

public void WhenISetTheScenarioPriceInZoneForProductPToN(string product, double price, string zone)

public void WhenISetTheScenarioPriceForProductPToN(string product, double price)

Now although the regex has not changed and so in theory will still greedily match, SpecFlow offers conversion to primitive types (and other types via custom conversion) so ignores the remainder of the sentence. This means it isn't ambiguous because it detects the final string parameter after the double (as opposed to not being able to decide whether a part of the sentence matches a string argument or has more arguments embedded).

like image 38
Adam Houldsworth Avatar answered Sep 16 '22 14:09

Adam Houldsworth