Cucumber-JVM 3 - io.cucumber.datatable.UndefinedDataTableTypeException

12,913

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: enter image description here

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.

Share:
12,913

Related videos on Youtube

silver
Author by

silver

Updated on October 14, 2022

Comments

  • silver
    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?

    UPDATE: enter image description here

  • silver
    silver almost 6 years
    Hi, can you also include the import statements? I am getting multiple suggestions.
  • silver
    silver almost 6 years
    Thanks, 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
    Grasshopper almost 6 years
    Can 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
    silver almost 6 years
    I 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.