Version number:
packages.config<PackageReference> tagsSpecFlow.Tools.MsBuild.Generation NuGet packageSpecFlowSingleFileGenerator custom toolDoes not apply, see commit.
Visual Studio 2019 - 16.8.0
Does not apply.
<Major>.<Minor>.<Patch> dotnet testDoes not apply, see commit.
When using a custom IValueRetriever to map a specific column names to a specific property, Retrieve is not being called while CanRetrieve returned true. This was unexpected to me.
Diving deeper into the Specflow sources to find test cases I noticed that there were testcases, but non of them were covering this scenario. I added a test case in this commit:
Is this a feature that should be working in the way I suspect, or is this indeed a bug?
If this is considered a bug: the issue is caused in file TEHelper.cs by GetMembersThatNeedToBeSet, which is checking the CanResolve but also requiring the column name to match exactly or on an alias. Which won't be the case in this scenario, resulting in Resolve not being called.
Potential workaround: use an TableAliasesAttribute, if possible (eg. not instantiating third party object.)
CanRetrieve.Retrieve is irrelevant, as it is not being called.Example:
```C#
public class ParentItem
{
public string Name { get; set; }
public ChildItem DutchItem { get; set; }
public ChildItem EnglishItem { get; set; }
}
public class ChildItem
{
public string ItemName { get; set; }
public string Language { get; set; }
}
///
/// Retrieves a ChildItem-objects for column's "Dutch name" and "English name" and maps them
/// to the corresponding "DutchItem" and "EnglishItem" properties of a ParentItem-object.
///
public class ChildItemValueRetriever : IValueRetriever
{
private static readonly IEnumerable
private static readonly IDictionary<string, string> ColumnNamesForWhichIRetrieveValues =
new Dictionary<string, string>
{
{ "Dutch name", "nl-NL" },
{ "English name", "en-US" }
};
public bool CanRetrieve(KeyValuePair<string, string> keyValuePair, Type targetType, Type type)
{
return TypesForWhichIRetrieveValues.Contains(type)
&& ColumnNamesForWhichIRetrieveValues.ContainsKey(keyValuePair.Key);
}
public object Retrieve(KeyValuePair<string, string> keyValuePair, Type targetType, Type propertyType)
{
return Parse(keyValuePair.Key, keyValuePair.Value);
}
public static ChildItem Parse(string columnName, string columnValue)
{
return new ChildItem
{
ItemName = columnValue,
Language = ColumnNamesForWhichIRetrieveValues[columnName]
};
}
}
```
See the following commit on my SpecFlow fork. It is based on the example above.
https://github.com/timvandenhof/SpecFlow/commit/dad342db4a67138714c8b8f598a2e8f338d4b6c6
@timvandenhof Could you send this failing tests as a PR? That would be lesser work for us to start debugging. Thanks!
@SabotageAndi Sure, I just opend draft PR #2207 for this issue.
PR contains test scenario for this issue, not a fix yet.
Also updated existing testscenario's to not use the deprecated Register methods.
Thanks! Having the test should it make it easier to debug to see what is happening
I'm suspecting this part in TEHelper.cs, method GetMembersThatNeedToBeSet:
C#
var properties = (from property in type.GetProperties()
from row in table.Rows
where TheseTypesMatch(type, property.PropertyType, row)
&& (IsMemberMatchingToColumnName(property, row.Id())
|| IsMatchingAlias(property, row.Id()))
select new MemberHandler { Type = type, Row = row, MemberName = property.Name, PropertyType = property.PropertyType, Setter = (i, v) => property.SetValue(i, v, null) }).ToList();
TheseTypesMatch will return true because there is a IValueRetriever available, however they are not IsMemberMatchingToColumnName and not IsMatchingAlias. Removing those checks will break other existing tests.
This is not a bug. Using TableAliasesattribute is the solution, not the workaround.
In your case, please use "Dutch name" and "English name" aliases.
public class ParentItem
{
public string Name { get; set; }
[TableAliases("Dutch name")]
public ChildItem DutchItem { get; set; }
[TableAliases("English name")]
public ChildItem EnglishItem { get; set; }
}
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.