Search code examples
bddspecflow

Specflow table column binding prevent Nulls


Given the following code:

public class Bob {
   public string Name { get; set; }
   public int Age { get; set; }
   public decimal Height { get; set; }
}

Feature: Bob checker

Scenario: Check Bob
  Given I have the following Bob
     | Name   | Age | Hieght |
     | Robert | 63  | 1.87   |
  When . . . . 
  Then . . . . 

[Given(@"I have the following Bob")]
public void IHaveTheFollowingBob(Table table) {
    var bob = table.CreateInstance<Bob>();
}

You'l notice the word 'Height' is not spelt correctly in the table. The CreateInstance method will still work but the 'Height' on the Bob object will be 0 or for reference type, null.

Is there a way to make SpecFlow fail if the column doesn't bind to the Type provided. Thanks


Solution

  • There is no such thing as throwing error if there is a column that does not match any of the class properties.

    However there is a work-arround. You may implement a method to check if there is an "invalid" column to prevent typos:

        [Given("I have the following Bob")]
        public void TestMethod1(Table table)
        {
            AssertAllTableColumnsMatch<Bob>(table);
    
            var bob = table.CreateInstance<Bob>();
        }
    
        public void AssertAllTableColumnsMatch<T>(Table table)
        {
            foreach (var header in table.Header)
            {
                bool columnHeaderMatches = HasProperty(typeof(T), header);
    
                Assert.IsTrue(columnHeaderMatches,
                    string.Format("The column header [{0}] does not match any property of the type [{1}]",
                    header, typeof(T).Name));
            }
        }
    
        private bool HasProperty(Type obj, string propertyName)
        {
            return obj.GetProperty(propertyName) != null;
        }
    

    The following error will be thrown: -> error: Assert.IsTrue failed. The column header [Hieght] does not match any property of the type [Bob]

    The method simply iterates all the columns and checks if the provided type has such property.