How do I create a Cucumber DataTable?

Christian picture Christian · Feb 11, 2014 · Viewed 34.2k times · Source

I want to manually set up a Cucumber DataTable using Java (instead of Gherkin).

In Gherkin, my table would look like this:

| h1 | h2 |
| v1 | v2 |

My Java so far looks like this:

List<String> raw = Arrays.asList( "v1", "v2");
DataTable dataTable = DataTable.create(raw, Locale.getDefault(), "h1", "h2");

What I get back is a DataTable with headers but no contents. It's also longer than expected:

  | h1| h2 |
  |   |    |
  |   |    |

I'm sure the solution must be fairly simple, but I'm a bit at a loss right now. What do I need to do to get my table?

Answer

Eric D. Johnson picture Eric D. Johnson · Feb 12, 2014

Hope this helps. If you're full Gherkins step looks like this...

When I see the following cooked I should say:
  | food  | say     |
  | Bacon | Yum!    |
  | Peas  | Really? |

You want this in Java. (Note that the cucumber.api.DataTable passed in is setup with your expected values before the test).

@When("^I see the following cooked I should say:$")
public void theFoodResponse(DataTable expectedCucumberTable) {
    // Normally you'd put this in a database or JSON
    List<Cuke> actualCukes = new ArrayList();
    actualCukes.add(new Cuke("Bacon", "Yum!"));
    actualCukes.add(new Cuke("Peas", "Really?")); 

    Another link to a Full Example.diff(actualCukes)
}

I will say that in the examples by Aslak Hellesøy he doesn't actually use the DataTable.

He would do your example something like this:

@When("^I see the following cooked I should say:$")
public void theFoodResponse(List<Entry> entries) {
    for (Entry entry : entries) {
        // Test actual app you've written
        hungryHuman.setInputValue(entry.food);
        hungryHuman.setOutputValue(entry.say);
    }
}

public class Entry {
    String food;
    String say;
}

For a Full Example for more reading check out:

  • Gherkins calculator: link
  • Java calculator Step Definitions: link

EDIT:

Sorry for the overkill @Christian, you perhaps didn't need the whole context of how to use it in an app, just a clean way to use DataTable.create and most of what I posted was another way to skin that cat with the Entry class (Which might be helpful for those reading this later.)

So the way you did it in your comment wasn't far off. I'm no pro at collections, so I can't give you any tips on making your 2D List of Strings, but I can clarify on the last two parameters (if you're using all 4).

  • If your columns are using Date or Calendar fields you can indicate a Format in the second to last param.
  • If you don't use the last one for Column Names, then it will automatically read your top line string for the column names.
  • Also you can drop the Locale.getDefault() and it will do that for you; so then you're looking at:

.

List<List<String>> infoInTheRaw = Arrays.asList( Arrays.asList("h1", "h2"),
    Arrays.asList("v1", "v2") ); 
DataTable dataTable = DataTable.create(infoInTheRaw);

You could also use the constructor which would be equally messy. :)