Cucumber-JVM 3 - io.cucumber.datatable.UndefinedDataTableTypeException
Solution 1
It has been totally revamped. XStream has been removed , so earlier code will not work.
You will need to add logic for datatable and parameter conversion. Refer to these - https://github.com/cucumber/cucumber/tree/master/datatable and https://github.com/cucumber/cucumber/tree/master/cucumber-expressions . Place below class code inside a package defined in the glue option.
public class Configurer implements TypeRegistryConfigurer {
@Override
public void configureTypeRegistry(TypeRegistry registry) {
registry.defineDataTableType(new DataTableType(Income.class, new TableEntryTransformer<Income>() {
@Override
public Income transform(Map<String, String> entry) {
return new Income(entry.get("name"),entry.get("amount"),entry.get("frequency"));
}
}));
}
@Override
public Locale locale() {
return Locale.ENGLISH;
}
}
UPDATED Imports... Not all are required, keep what is relevant
import cucumber.api.TypeRegistry;
import cucumber.api.TypeRegistryConfigurer;
import io.cucumber.cucumberexpressions.ParameterType;
import io.cucumber.datatable.DataTable;
import io.cucumber.datatable.DataTableType;
import io.cucumber.datatable.TableCellTransformer;
import io.cucumber.datatable.TableEntryTransformer;
import io.cucumber.datatable.TableRowTransformer;
import io.cucumber.datatable.TableTransformer;
Solution 2
Use DataTableType annotation
@DataTableType
public Income incomeEntry(Map<String, String> entry) {
return new Income(entry.get("name"), entry.get("amount"), entry.get("frequency"));
}
Then you can directly use the list of the custom class in step definition
@When("^I Enter My Regular Income Sources$")
public void I_Enter_My_Regular_Income_Sources(List<Income> incomes) throws Throwable {
// More code
}
Solution 3
Migrating from v2.x.x to v3.x.x for DataTable
Posting my answer to serve as reference for those who may encounter the same. For their release announcement, click here.
I decided to put DataTableConfigurer.java
in its own package so it does not mix with my stepdefs:
Runner:
@CucumberOptions(features = { "src/test/resources/features" }, tags = { "not @ignore" }, glue = {
"jcucumberng/steps/defs", "jcucumberng/steps/config", "jcucumberng/steps/hooks" }, ...
DataTableConfigurer:
import java.util.Locale;
import java.util.Map;
import cucumber.api.TypeRegistry;
import cucumber.api.TypeRegistryConfigurer;
import io.cucumber.datatable.DataTableType;
import io.cucumber.datatable.TableEntryTransformer;
import jcucumberng.steps.domain.Expense;
import jcucumberng.steps.domain.Income;
/*
* Maps datatables in feature files to custom domain objects.
*/
public class DataTableConfigurer implements TypeRegistryConfigurer {
@Override
public Locale locale() {
return Locale.ENGLISH;
}
@Override
public void configureTypeRegistry(TypeRegistry registry) {
registry.defineDataTableType(new DataTableType(Income.class, new TableEntryTransformer<Income>() {
@Override
public Income transform(Map<String, String> entry) {
return new Income(entry.get("name"), entry.get("amount"), entry.get("frequency"));
}
}));
registry.defineDataTableType(new DataTableType(Expense.class, new TableEntryTransformer<Expense>() {
@Override
public Expense transform(Map<String, String> entry) {
return new Expense(entry.get("name"), entry.get("amount"), entry.get("frequency"));
}
}));
}
}
I had another custom domain type Expense
(which happened to have the same fields), so I just registered it again based on the example.
Related videos on Youtube
silver
Updated on October 14, 2022Comments
-
silver over 1 year
I updated from Cucumber-JVM 2.4.0 to 3.0.2 in my
pom.xml
and DataTables started throwing this exception:io.cucumber.datatable.UndefinedDataTableTypeException: Can't convert DataTable to List< jcucumberng.steps.pojos.Income >. Please register a DataTableType with a TableEntryTransformer or TableRowTransformer for class jcucumberng.steps.pojos.Income
I changed all my imports to
import io.cucumber.datatable.DataTable;
I did an
mvn clean install
and compilation was successful but steps involving DataTables no longer work after the update.Current code:
// Feature When I Enter My Regular Income Sources | name | amount | frequency | | Salary | 25000 | every 2 weeks | // Stepdef @When("^I Enter My Regular Income Sources$") public void I_Enter_My_Regular_Income_Sources(DataTable dataTable) throws Throwable { List<Income> incomes = dataTable.asList(Income.class); // More code } // Custom type public class Income { private String name = null; private String amount = null; private String frequency = null; public Income(String name, String amount, String frequency) { this.name = name; this.amount = amount; this.frequency = frequency; } // Getters and setters }
Is there a new way to use the DataTables in Cucumber-JVM v3.x.x?
-
silver almost 6 yearsIssue #1388 is now open in GitHub.
-
Grasshopper almost 6 yearsI am attempting a kind of guide for Cucumber 3 migration at this link - github.com/grasshopper7/cuke3-migration. Just started and is a total work in progress. Maybe this helps out.
-
Grasshopper almost 6 yearsFinally got time to finish up. Divided into 2 - parameter github.com/grasshopper7/cuke3-migrate-parametertype and datatable github.com/grasshopper7/cuke3-migrate-datatabletype. Would appreciate any feedback. Thanks
-
-
silver almost 6 yearsHi, can you also include the import statements? I am getting multiple suggestions.
-
silver almost 6 yearsThanks, I added the imports. I copied the
Configurer
class in the same package where the *Steps.java classes are but I am getting above error for constructor (see added screenshot). -
Grasshopper almost 6 yearsCan u add the whole class including the imports section? What is the version of datatable.jar and datatable-dependencies in imported maven jars? I have 1.0.3
-
silver almost 6 yearsI got it to work. I needed to import the (custom) Income.class. The red underlines were overlapping in Eclipse IDE. Thank you, Grasshopper, your links and example were absolutely helpful. Upvoted and accepted answer. My datatable jars are also 1.0.3.