java 如何将 Cucumber 中的 DataTable 转换为对象列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46130455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:04:52  来源:igfitidea点击:

How to convert a DataTable in Cucumber to a List of objects?

javacucumber

提问by silver

Original Title: What does scalar mean in Cucumber DataTables in Java?

原标题:Java 中 Cucumber DataTables 中的标量是什么意思?

From thisreference:

这个参考:

Java provides several scalar types. These include primitive numeric types, plus boolean and char.

Every scalar (primitive) type has an associated wrapper class or reference type.

Java 提供了几种标量类型。这些包括原始数字类型,以及布尔值和字符。

每个标量(原始)类型都有一个关联的包装类或引用类型。

Reading the javadocs:

阅读javadocs:

/**
  * Converts the table to a List.
  *
  * If {@code itemType} is a scalar type the table is flattened.
  *
  * Otherwise, the top row is used to name the fields/properties and the remaining
  * rows are turned into list items.
  *
  * @param itemType the type of the list items
  * @param <T>      the type of the list items
  * @return a List of objects
  */
public <T> List<T> asList(Class<T> itemType) {
    return tableConverter.toList(this, itemType);
}

/**
  * Converts the table to a List of List of scalar.
  *
  * @param itemType the type of the list items
  * @param <T>      the type of the list items
  * @return a List of List of objects
  */
public <T> List<List<T>>> asLists(Class<T> itemType) {
    return tableConverter.toLists(this, itemType);
}

However, I was able to pass String.class in asList():

但是,我能够在 asList() 中传递 String.class:

List<String> list = dataTable.asList(String.class);

A String is not a primitive in Java. I would like some clarification on what "scalar" means in this context.

String 不是 Java 中的原语。我想澄清一下“标量”在这种情况下的含义。

采纳答案by Thomas Kl?ger

I did not find an explicit definition about what Cucumber for Java means with scalar type.

我没有找到关于 Cucumber for Java 与scalar type.

The best hint I could find was in the snippet that is produced for new steps that accept a DataTable. The generated comment reads:

我能找到的最好的提示是在为接受DataTable. 生成的评论如下:

For automatic transformation, change DataTable to one of List<YourType>, List<List<E>>, List<Map<K,V>> or Map<K,V>. E,K,V must be a scalar (String, Integer, Date, enum etc)

对于自动转换,将 DataTable 更改为 List<YourType>、List<List<E>>、List<Map<K,V>> 或 Map<K,V> 之一。E、K、V 必须是标量(字符串、整数、日期、枚举等)

So it seems that besides the "Java scalar types" (byte, short, int, long, char, boolean, or respectively their wrapper types Byte, Short, Integer, Long, Charand Boolean) you can also use String, java.util.Dateand enum types.

如此看来,除了“Java的标量类型”( ,byteshortintlongcharboolean分别或它们的包装类型ByteShortIntegerLongCharBoolean),你也可以使用Stringjava.util.Date和枚举类型。

Actually, a short test showed that I can use any type that has a constructor with a single Stringas parameter.

实际上,一个简短的测试表明我可以使用具有单个String作为参数的构造函数的任何类型。



A small example with my own value class (very contrived). The output from the following snippets is a List<List<MyValueClass>>.

一个带有我自己的价值类的小例子(非常做作)。以下片段的输出是一个List<List<MyValueClass>>.

// MyValueClass.java
public class MyValueClass {

    private final String value;

    public MyValueClass(String v) {
        this.value = v;
    }

    public String getValue() {
        return value;
    }
}

// snippet from MySteps.java
@Given("^a table with$")
public void a_table_with(DataTable arg1) throws Throwable {
    System.out.println(arg1.asLists(MyValueClass.class));
}

// snippet from my test1.feature
  Scenario: Test with Datatable
    Given a table with
      | a | b | c |
      | 1 | 2 | 3 |
      | a | b | c |

回答by silver

Quoting the generated code snippet:

引用生成的代码片段:

// For automatic transformation, change DataTable to one of
// List<YourType>, List<List<E>>, List<Map<K,V>> or Map<K,V>.
// E,K,V must be a scalar (String, Integer, Date, enum etc)

"Scalar" from the Cucumber javadocs may have been incorrectly used to collectively mean the associated wrapper classof the primitives (i.e. scalar) among other things.

来自 Cucumber javadocs 的“标量”可能被错误地用于统称原语(即标量)的相关包装类等。



From below example, asList()proceeds to create a List of the user defined Expense object as per docs:

从下面的示例中,asList()继续根据文档创建用户定义的费用对象的列表:

Otherwise, the top row is used to name the fields/properties and the remaining rows are turned into list items.

否则,顶行用于命名字段/属性,其余行变成列表项。

I have observed the following:

我观察到以下情况:

  1. The top row (header) in the Feature file must matchthe field names of the object.
  2. The constructor may accept all fields as parameters.
  1. Feature 文件中的顶行(标题)必须对象的字段名称匹配
  2. 构造函数可以接受所有字段作为参数。

User Defined Object (Non-Scalar):

用户定义对象(非标量):

public class Expense {

    private String name = null;
    private String amount = null;
    private String frequency = null;

    public Expense(String name, String amount, String frequency) {
        this.name = name;
        this.amount = amount;
        this.frequency = frequency;
    }

    // Getters and setters
}

Feature:

特征:

When I Enter My Regular Expenses
  | name        | amount | frequency     |
  | Electricity |   5500 | Monthly       |
  | Water       |    900 | Weekly        |
  | Internet    |   1900 | Every 2 Weeks |
  | Cable TV    |    555 | Daily         |

Step Def:

步骤定义:

@When("^I Enter My Regular Expenses$")
public void I_Enter_My_Regular_Expenses(DataTable dataTable) throws Throwable {
  List<Expense> expenseList = dataTable.asList(Expense.class);

  for (Expense expense : expenseList) {
    System.out.println(expense);
  }

  // Here, asList() creates a List of Expense objects.
}

Output:

输出:

output

输出

回答by Mujeeb007

Declare the argument as a List, but don't define any capture groups in the expression:

将参数声明为 List,但不要在表达式中定义任何捕获组:

If the Datatable contains only one column then Data Table is automatically flattened to a List by Cucumber (using DataTable.asList(String.class)) before invoking the step definition.

如果数据表仅包含一列,则在调用步骤定义之前,数据表会自动按 Cucumber 展平为列表(使用 DataTable.asList(String.class))。

回答by Saravanakumar B

For Lower Versions use the below implementation.

对于较低版本,请使用以下实现。

Datatable.feature

数据表功能

When Datatable to Pojo
 |  field1  |  field1Value1  | field1Value2  |
 |  field2  |  field2Value1  | field2Value2  |
 |  field3  |  field3Value1  | field3Value2  |
 |  field4  |  field4Value1  | field4Value2  |
 |  field5  |  field5Value1  | field5Value2  |

Pojo.class

Pojo类

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Pojo {

private String field1;
private String field2;
private String field3;
private String field4;
private String field5;

}

StepDefinition.class

步骤定义类

@Given("Datatable to Pojo")
public void method (DataTable dataTable){
    List<Pojo> pojoList = new ArrayList<Pojo>();
    List<Map<String,String>> mapList = dataTable.transpose().asMaps();
    for(Map<String, String> map : mapList) {
        pojoList.add(new ObjectMapper().convertValue(map, Pojo.class));
    }
}