黄瓜 JVM 3 - io.cucumber.datatable.UndefinedDataTableTypeException
Cucumber-JVM 3 - io.cucumber.datatable.UndefinedDataTableTypeException
我在 pom.xml
中从 Cucumber-JVM 2.4.0 更新到 3.0.2,DataTables 开始抛出此异常:
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
我将所有导入更改为
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?
更新:
它已经完全改版了。 XStream 已被删除,因此之前的代码将不起作用。
您需要添加数据表和参数转换的逻辑。请参阅这些 - https://github.com/cucumber/cucumber/tree/master/datatable and https://github.com/cucumber/cucumber/tree/master/cucumber-expressions 。将下面的 class 代码放在 glue 选项中定义的包内。
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;
从 v2.x.x 迁移到 v3.x.x DataTable
贴出我的回答,供有相同情况的朋友参考。对于他们的发布公告,请单击 here。
我决定将 DataTableConfigurer.java
放在自己的包中,这样它就不会与我的 stepdefs 混合:
亚军:
@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
(恰好有相同的字段),所以我只是根据示例重新注册了它。
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
}
使用 DataTableType 注解
@DataTableType
public Income incomeEntry(Map<String, String> entry) {
return new Income(entry.get("name"), entry.get("amount"), entry.get("frequency"));
}
然后就可以在步骤定义中直接使用自定义class的列表
@When("^I Enter My Regular Income Sources$")
public void I_Enter_My_Regular_Income_Sources(List<Income> incomes) throws Throwable {
// More code
}
我在 pom.xml
中从 Cucumber-JVM 2.4.0 更新到 3.0.2,DataTables 开始抛出此异常:
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
我将所有导入更改为
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?
更新:
它已经完全改版了。 XStream 已被删除,因此之前的代码将不起作用。
您需要添加数据表和参数转换的逻辑。请参阅这些 - https://github.com/cucumber/cucumber/tree/master/datatable and https://github.com/cucumber/cucumber/tree/master/cucumber-expressions 。将下面的 class 代码放在 glue 选项中定义的包内。
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;
从 v2.x.x 迁移到 v3.x.x DataTable
贴出我的回答,供有相同情况的朋友参考。对于他们的发布公告,请单击 here。
我决定将 DataTableConfigurer.java
放在自己的包中,这样它就不会与我的 stepdefs 混合:
亚军:
@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
(恰好有相同的字段),所以我只是根据示例重新注册了它。
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
}
使用 DataTableType 注解
@DataTableType
public Income incomeEntry(Map<String, String> entry) {
return new Income(entry.get("name"), entry.get("amount"), entry.get("frequency"));
}
然后就可以在步骤定义中直接使用自定义class的列表
@When("^I Enter My Regular Income Sources$")
public void I_Enter_My_Regular_Income_Sources(List<Income> incomes) throws Throwable {
// More code
}