CreateInstance in SpecFlow.Assist skips row element when enum has the same value as the name of row parameter
SpecFlow Version
3.9.74
Which test runner are you using?
SpecFlow+ Runner
Test Runner Version Number
3.9.31
.NET Implementation
equal or greater .NET Framework 4.6.1
Project Format of the SpecFlow project
Sdk-style project format
.feature.cs files are generated using
SpecFlow.Tools.MsBuild.Generation NuGet package
Test Execution Method
Visual Studio Test Explorer
SpecFlow Section in app.config or content of specflow.json
{
"language": {
"feature": "de-AT"
},
"bindingCulture": {
"name": "de-AT"
},
"unitTestProvider": {
"name": "specrun"
},
"runtime": {
"missingOrPendingStepsOutcome": "Error"
},
"stepAssemblies": [
{ "assembly": "AppServer.Shared.SpecFlow" }
]
}
Issue Description
Assuming you have an enum called "MyEnum" That enum has several values, one of them is "MyEnum" You use that enum in your row, you call the property "MyEnum" in the binding (or use MyEnum as its TableAlias).
if you use Specflow.Assist CreateInstance to convert this value from the string in the feature file to an enum in the step definition, the value is skipped IF and ONLY IF the enum in question is the same as the property name or table alias. Once skipped, the next value in the table is attempted to be used. If there are type differences (e.g. enum and DateTime as in the example), the type mismatch leads to an error. If more enums are used that are not named the same as your property, the parsing works correctly.
This issue appeared when upgrading from Specflow Version 3.9.8 to 3.9.74, I cannot say which version broke it exactly.
Steps to Reproduce
Use the following Binding and enum:
[Binding]
public class SampleRow
{
public MyEnum MyEnum { get; set; }
public DateTime MyDate { get; set; }
[Given(@"following fields exist:")]
public void GivenFollowingFieldsExist(SampleRow row) { }
}
[Binding]
public static class Transformations
{
[StepArgumentTransformation]
public static SampleRow SampleRowTransformation(Table table)
{
return table.CreateInstance<SampleRow>();
}
}
public enum MyEnum
{
MyEnum = 0,
HisEnum = 1,
HerEnum = 2
}
Use the following feature file:
Funktionalität: Enum-Test
Szenario: Enum-Test
Angenommen following fields exist:
| MyEnum | MyDate |
| <MyEnum> | <MyDate> |
Beispiele:
| MyEnum | MyDate |
| MyEnum | 01.01.2020 |
| HisEnum | 01.01.2020 |
| HerEnum | 01.01.2020 |
Cases "HisEnum" and "HerEnuM" work. Case "MyEnum" breaks with the following error message: No enum with value '01.01.2020' found for Table row column 'MyEnum'. -> Requested value '01.01.2020' was not found.
Link to Repro Project
No response
I found the issue. SpecFlow thinks the table is a horizontal table and not a vertical table. It is because the table is so small (only 1 row, 2 columns) and the first row value is the same name as a property. Code is here: https://github.com/SpecFlowOSS/SpecFlow/blob/master/TechTalk.SpecFlow/Assist/TEHelpers.cs#L222
So simply switching the order of the columns in the Scenario will fix it.
Tbh, I have no idea to fix this without breaking other people. This is so an absolute edge case.