Reputation: 77
I have to following SpecFlow code:
And I get and validate parameters
| ParameterName| Value | Answers | Mandatory | Meta | Modified | ReadOnly | Submit | SubmitValues | Tag |
| SurName | | | true | | false | false | true | | input |
| Name | | | true | | false | false | false | | input |
.....
And i want this table to convert it into a Dictionary<string, List<string>>
, the head columns will be the keys and the rest of the information will be the values. I hardcoded some values:
Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
dictionary.Add("ParameterName", new List<string> {"SurName", "Name", "Age"});
dictionary.Add("Value", new List<string> { "", "", "" });
dictionary.Add("Answers", new List<string> { "", "", "" });
dictionary.Add("Mandatory", new List<string> { "true", "true", "true" });
dictionary.Add("Meta", new List<string> { "", "", "" });
dictionary.Add("Modified", new List<string> { "false", "false", "false" });
dictionary.Add("ReadOnly", new List<string> { "false", "false", "false" });
dictionary.Add("Submit", new List<string> { "true", "false", "true" });
dictionary.Add("SubmitValues", new List<string> { "", "", "" });
dictionary.Add("Tag", new List<string> { "input", "input", "select" });
But the actual table has a lot of values and i need to do this for all of them, and they might change, that's why i don't need a hardcoded dictionary. How can I do this?
Upvotes: 0
Views: 8871
Reputation: 25
It's too late to answer this question but probably might be helpful for others.
The better way to handle such data in collection should be in format List>.
Following extension method should help in this regard-
public static List<Dictionary<string, string>> ConvertToDictionaryList(this Table dt)
{
var lstDict = new List<Dictionary<string, string>>();
if (dt!=null)
{
var headers = dt.Header;
foreach (var row in dt.Rows)
{
var dict = new Dictionary<string, string>();
foreach (var header in headers)
{
dict.Add(header, row[header]);
}
lstDict.Add(dict);
}
}
return lstDict;
}
But if you still want to use Dictionary>, then you can use following snippet
public static List<Dictionary<string, string>> ConvertToDictionaryList(this Table dt)
{
var lstDict = new Dictionary<string, List<string>>();
if (dt != null)
{
var headers = dt.Header;
foreach (var row in dt.Rows)
{
foreach (var header in headers)
{
if (lstDict.ContainsKey(header))
{
lstDict[header].Add(row[header]);
}
else
{
lstDict.Add(header, new List<string> { row[header] });
}
}
}
}
return lstDict;
}
Upvotes: 0
Reputation: 5835
You could also use the CreateSet extension method from the TechTalk.SpecFlow.Assist namespace.
Have a look at the documentation here: http://specflow.org/documentation/SpecFlow-Assist-Helpers/
Small example:
CreateSet is an extension method off of Table that will convert the table data to a set of objects. For example, if you have the following step:
Given these products exist
| Sku | Name | Price |
| BOOK1 | Atlas Shrugged | 25.04 |
| BOOK2 | The Fountainhead | 20.15 |
You can convert the data in the table to a set of objects like so:
[Given(@"Given these products exist")]
public void x(Table table)
{
var products = table.CreateSet<Product>();
// ...
}
Upvotes: 0
Reputation: 18023
In such a dictionary the retrieval of the same row is quite awkward (you should index the Value lists)...
Instead, I would create a List<TestParameters>
where TestParameters
class contains a row with normal strongly typed properties:
public class TestParameters
{
public string ParameterName { set; set; }
public int Value { set; set; }
public bool Mandatory { set; set; }
// etc.
}
So now you have somewhere a test step like this:
[Given(@"I get and validate parameters")]
public void GetParameters(Table parameters)
{
}
Simply replace the Table
with your more specific type:
[Given(@"I get and validate parameters")]
public void GetParameters(List<TestParameters> parameters)
{
}
And just define a Table->List transformation step in a helper class:
[Binding]
public class Transformations
{
[StepArgumentTransformation]
public List<TestParameters> GetTestParameters(Table table)
{
return table.Rows.Select(row => new TestParameters
{
// string prop
ParameterName = row["ParameterName"],
// int prop
Value = !String.IsNullOrEmpty(row["Value"]) ? Int32.Parse(row["Value"]) : 0,
// bool prop
Mandatory = row["Mandatory"]?.ToLowerInvariant() == "true"
// TODO: other properties
}).ToList();
}
}
Of course, the result of the transformation can be Dictionary<string, List<string>>
, too, if you really insist to that...
Upvotes: 2