【问题标题】:Cucumber-JVM 3 - io.cucumber.datatable.UndefinedDataTableTypeExceptionCucumber-JVM 3 - io.cucumber.datatable.UndefinedDataTableTypeException
【发布时间】:2018-06-09 07:16:59
【问题描述】:

我在pom.xml 中从 Cucumber-JVM 2.4.0 更新到 3.0.2,DataTables 开始抛出此异常:

io.cucumber.datatable.UndefinedDataTableTypeException:无法转换 数据表列出。请注册一个 带有 TableEntryTransformer 或 TableRowTransformer 的 DataTableType 类 jcucumberng.steps.pojos.Income

我将所有导入更改为

import io.cucumber.datatable.DataTable;

我做了一个mvn clean install,编译成功,但更新后涉及 DataTables 的步骤不再起作用。

当前代码:

// 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
}

在 Cucumber-JVM v3.x.x 中是否有一种使用 DataTables 的新方法?

更新:

【问题讨论】:

标签: java datatable cucumber cucumber-jvm


【解决方案1】:

它已被彻底改造。 XStream 已被删除,因此早期的代码将无法使用。

您需要为数据表和参数转换添加逻辑。请参阅这些 - https://github.com/cucumber/cucumber/tree/master/datatablehttps://github.com/cucumber/cucumber/tree/master/cucumber-expressions 。将下面的类代码放在胶水选项中定义的包内。

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;
            }

        }

更新 进口...并非全部都是必需的,保留相关的内容

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;

【讨论】:

  • 您好,您能否也包括导入语句?我收到了多项建议。
  • 谢谢,我添加了导入。我将 Configurer 类复制到 *Steps.java 类所在的同一个包中,但构造函数出现错误(参见添加的屏幕截图)。
  • 你可以添加整个类,包括导入部分吗?导入的 maven jar 中的 datatable.jar 和 datatable-dependencies 的版本是什么?我有 1.0.3
  • 我让它工作了。我需要导入(自定义)Income.class。红色下划线在 Eclipse IDE 中重叠。谢谢你,蚱蜢,你的链接和例子绝对有帮助。赞成并接受的答案。我的数据表 jar 也是 1.0.3。
【解决方案2】:

DataTable 从 v2.x.x 迁移到 v3.x.x

发布我的答案,以供可能遇到相同问题的人参考。对于他们的发布公告,请点击here

我决定将 DataTableConfigurer.java 放在自己的包中,这样它就不会与我的 stepdef 混合:

跑步者:

@CucumberOptions(features = { "src/test/resources/features" }, tags = { "not @ignore" }, glue = {
        "jcucumberng/steps/defs", "jcucumberng/steps/config", "jcucumberng/steps/hooks" }, ...

数据表配置器:

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"));
            }
        }));
    }

}

我有另一个自定义域类型Expense(恰好有相同的字段),所以我只是根据示例重新注册。

【讨论】:

    【解决方案3】:

    使用DataTableType注解

    @DataTableType
    public Income incomeEntry(Map<String, String> entry) {
        return new Income(entry.get("name"), entry.get("amount"), entry.get("frequency"));
    }
    

    那么就可以直接使用步骤定义中自定义类的列表了

    @When("^I Enter My Regular Income Sources$")
    public void I_Enter_My_Regular_Income_Sources(List<Income> incomes) throws Throwable {
        // More code    
    }
    

    【讨论】:

      【解决方案4】:
          I have created a code which won't use **DataTable** concept. You can update this below implementation so that you won't get any failures in your scripts in future.
      
          CucumberUtil.java:
          -----------------
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
      
          public class CucumberUtil {
      
      // public static synchronized Map<String, String> TableDictionaryConverter(DataTable table) {                    -- removed this concept because of version issues in DataTable
         public static synchronized Map<String, String> TableDictionaryConverter(List<List<String>> data) {
                Map<String, String> mapTable = new HashMap<String, String>();
                for(List<String> rows: data) {
                       mapTable.put(rows.get(0), rows.get(1)); 
                }
                return mapTable;
         }
      
      // Feature
      When I Enter My Regular Income Sources
        | name     | Salary        | 
        | amount   | 25000         | 
        | frequency| every 2 weeks |
      
      // Stepdef
      @When("^I Enter My Regular Income Sources$")
      public void I_Enter_My_Regular_Income_Sources(List<List<String>> table) throws Throwable {
      
          Map<String, String> mapTable = CucumberUtil.TableDictionaryConverter(table);
      
          String nameValue = mapTable.get("name");         // Salary
          String amountValue = mapTable.get("name");       // 25000
          String frequencyValue = mapTable.get("name");    // every 2 weeks
      
          // More code    
      }
      

      【讨论】:

        猜你喜欢
        • 2019-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多