I took your advise in regards to the ORM mapping names, not sure why i
didn't think of that. I also downloaded the branch you suggested to
try out the FillInstance extension method. After some use i found a
few things
It can be very fragile, if there is a problem converting any property
you can't just handle the exception and manually update it later
because it stops filling the instance as soon as it hits an
exception.
To me it makes a lot of sense to have your Feature files readable and
understandable by everyone not just developers that understand the
underlying code. Because of this i think its important to use english
words and then convert them to the correct logical value in your unit
test. For example he have a numeric system (0,1,2,3) that represents a
date period in our system. in the feature it would make more sense to
say Weekly, Fortnightly, Four Weekly and Monthly.
To get around this i played with the idea of having a PropertyOverride
that you pass to the FillInstance method. I ended up with this method
private static void LoadInstanceWithKeyValuePairs<T>(Table
table, T instance, List<PropertyInfo> overrideProperties)
{
var handlers = GetTypeHandlersForFieldValuePairs<T>();
var propertiesThatNeedToBeSet = from property in
typeof(T).GetProperties()
where !
overrideProperties.Contains(property)
from key in handlers.Keys
from row in table.Rows
where
key.IsAssignableFrom(property.PropertyType)
&&
IsPropertyMatchingToColumnName(property, row["Field"])
select new { Row = row,
property.Name, Handler = handlers[key] };
propertiesThatNeedToBeSet.ToList()
.ForEach(x => instance.SetPropertyValue(x.Name,
x.Handler(x.Row, x.Row["Value"])));
}
I think this worked by i then struck another issue. Because of this
bug with specflow
https://github.com/techtalk/SpecFlow/issues#issue/44
i had to start entering values in for fields that might be null. In
this case i entered the word Null and then had an extension method for
a string that would convert it into the correct nullable type. The
FillInstance method however does not understand this and it will cause
it to fail. I then played around with a typeHandlerOverrides parameter
where you could override the typehandler for the specified type and
point it to a new method. but my lack of knowledge seemed to hit a
problem. I was passing it a this
var typeHandlerOverrides = new Dictionary<Type,
Func<TableRow, string, object>>
{
{typeof (int?), (TableRow row,
string id) => "Value".ToIntNullable()},
{typeof (decimal?), (TableRow
row, string id) => "Value".ToDecimalNullable()},
{typeof (DateTime?), (TableRow
row, string id) => "Value".ToDateTimeNullable()},
};
table.FillInstance(contact, overrideProperties,
typeHandlerOverrides);
This didn't seem to change anything though, i think the problem is
that specflow dosn't have the correct references to access my custom
converter methods.
Either way i think the FillInstance still needs a way you can create
customer type converters and custom property converters (because
sometimes just a type conversion is not logical). I think you might be
able to create some converter type in speflow and then from that but
i'll have to have a ponder over this. Any thoughts?