Answer
@DataTableType — Custom Object Mapping for Data Tables
The Problem Without @DataTableType
Java
// Without custom type — messy manual mapping
@When("the admin creates these users:")
public void createUsers(DataTable dataTable) {
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
for (Map<String, String> row : rows) {
String name = row.get("name");
String email = row.get("email");
String role = Role.valueOf(row.get("role")); // manual conversion
int age = Integer.parseInt(row.get("age")); // manual conversion
createUser(name, email, role, age);
}
}
Solution: @DataTableType with POJO
Java
// User POJO
public class UserData {
public String name;
public String email;
public String role;
public int age;
public UserData(String name, String email, String role, int age) {
this.name = name;
this.email = email;
this.role = role;
this.age = age;
}
}
// DataTableTypeRegistry.java — define the transformation
public class DataTableTypeRegistry {
@DataTableType
public UserData userEntry(Map<String, String> entry) {
return new UserData(
entry.get("name"),
entry.get("email"),
entry.get("role"),
Integer.parseInt(entry.get("age"))
);
}
@DataTableType
public ProductData productEntry(Map<String, String> entry) {
return new ProductData(
entry.get("name"),
new BigDecimal(entry.get("price").replace("$", "")),
entry.get("category")
);
}
}
Feature File
Gherkin
Scenario: Admin creates multiple users
When the admin creates these users:
| name | email | role | age |
| John Doe | john@example.com | ADMIN | 30 |
| Jane Smith| jane@example.com | MANAGER | 28 |
| Bob Lee | bob@example.com | USER | 25 |
Then all 3 users should appear in the user management list
Clean Step Definition
Java
@When("the admin creates these users:")
public void createUsers(List<UserData> users) { // ← Cucumber auto-converts
for (UserData user : users) {
adminPage.createUser(user.name, user.email, user.role);
}
}
@Then("all {int} users should appear in the user management list")
public void verifyUsers(int expectedCount) {
assertEquals(expectedCount, adminPage.getUserCount());
}
Single Row → Object (not List)
Java
// Feature file
When the user updates their profile to:
| firstName | John |
| lastName | Doe |
| phone | 9876543 |
// Step definition receives a single object
@When("the user updates their profile to:")
public void updateProfile(UserData updatedData) { // ← single object
profilePage.updateName(updatedData.firstName + " " + updatedData.lastName);
profilePage.updatePhone(updatedData.phone);
}
@DocStringType for Multi-line Strings
Java
// For JSON/XML in feature files:
@DocStringType
public JsonNode json(String docString) throws Exception {
return new ObjectMapper().readTree(docString);
}
// Feature file:
When I send request with body:
"""json
{"name": "John", "role": "ADMIN"}
"""
