Currently, the argument matching between the constants specified in the DataRow attribute and the corresponding method parameters appears to be done using basic reflection plus direct argument passing without any processing. This ends up enforcing exact matches on types most of the time. Due to this, advanced scenarios like converting strings to Type objects or Uri instances for example are not supported.
Adding support for the TypeConverter-based system during the matching phase would allow richer scenarios without having to fallback to using [DynamicData()] which leads to more complex code overall.
Creating TypeConverter classes is a very common and widely used mechanism to allow conversions between arbitrary types, so supporting them wouldn't create coupling in the test framework to anything non-standard.
For more information on the TypeConverter and TypeDescriptor system, here is the main page:
Notice from the inheritance tree how much converters are used. A few very useful ones that could be leveraged for testing:
Keep in mind that to support these there is no need to create custom implementations for each one: just fetching the TypeDescriptor for an object generically will already ensure the default TypeConverter is used for that type.
This is what I'm proposing:
[DataTestMethod]
[DataRow("http://www.google.com")]
[DataRow("http://www.github.com")]
public void MyTest(Uri url)
{
...
}
The strings passed in the DataRow attribute should be converted into the parameters in the method respecting the specified TypeConverter applied on the parameter type.
Because the Uri type already references the UriTypeConverter via an attribute (from referencesource, this would work automatically without having to specify any converter on the argument itself:
[Serializable]
[TypeConverter(typeof(UriTypeConverter))]
public partial class Uri : ISerializable {
An exception is thrown:
Result1 StackTrace:
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Hi @julealgon, currently the DynamicData attribute is the only way to achieve this. This is a completely valid ask hence marking this issue as up-for-grabs and enhancement. You can raise a PR for the same and we'll be happy to take a look.
Have been a while since this issue was opened, and was wondering if @julealgon or anyone else is working on it, or plan to do it? Otherwise, I can take this up, and make a PR with the proper changes.
Let me know, thanks!
Sorry I missed your comment @parrainc . I have not managed to look into this one yet, unfortunately.
Been a while tho;
I'll see if I manage to get some time and put some code for this.
Most helpful comment
Hi @julealgon, currently the
DynamicDataattribute is the only way to achieve this. This is a completely valid ask hence marking this issue asup-for-grabsandenhancement. You can raise a PR for the same and we'll be happy to take a look.