Tabular Input and Output in JBehave
Let's start with a story: Given a table of factors: |first|second| |4 |5 | |3 |2 | |8 |8 | When math is done Then I should have: |product|sum| |20 |9 | |6 |5 | |64 |16 |
We want to read in the values from the input table and check them against the expected values in the output table.
We'll need steps:
@Given("a table of factors:$factors)
public void factors(ExamplesTable inputTable) {
inputData = inputTable;
}
The ExamplesTable is basically a List of rows stored as Maps keyed by the column headers.
There's two bits of magic. The first is storing the actual results in a List of Maps that uses the same keys as the headers of the output table, in this case "product" and "sum".
@When("math is done")
public void math() {
results = new ArrayList<Map<String, Integer>>();
for(Parameters parameter : inputData.getRowsAsParameters()) {
// Get the columns by header
int first = parameter.valueAs("first", Integer.class);
int second = parameter.valueAs("second", Integer.class);
HashMap<String, Integer> resultMap = new HashMap<String, Integer>();
// put them in a map by out table header
resultMap.put("product", first * second);
resultMap.put("sum", first + second);
results.add(resultMap);
}
}
The second bit of magic is adding Hamcrest matchers to the OutcomesTable so JBehave can do the comparison then calling verify() on the table.
@Then("I should have:$resultTable")
public void results(ExamplesTable table) {
OutcomesTable expected = new OutcomesTable();
for (int i = 0; i < results.size();i++) {
Parameters row = resultTable.getRowAsParameters(i);
Map<String, Integer> actual = results.get(i);
for (String key : actual.keySet()) {
expected.addOutcome(key, actual.get(key), (Matchers.equalTo(row.valueAs(key, Integer.class))));
}
}
expected.verify();
}
The parameters for addOutcome(key, actual, matcher) are
- key:
the header in the outcome table
- actual:
actual value determined in the When clause
- matcher:
a Hamcrest matcher to do the comparison
You don't have to store the intermediate actual values in List<Map