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

时间:2017-09-09 12:02:37

标签: java cucumber

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

来自this参考:

  

Java提供了几种标量类型。这些包括原始数字   types,加上boolean和char。

     

每个标量(基元)类型都有一个关联的包装类或   参考类型。

阅读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);
}

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

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

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

4 个答案:

答案 0 :(得分:6)

引用生成的代码段:

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

&#34;标量&#34;来自Cucumber javadocs可能被错误地用于统称表示基元的关联 包装类 (即标量)等。

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

  

否则,顶行用于命名字段/属性和   剩余的行将变为列表项。

我观察到以下情况:

  1. 要素文件中的第一行(标题)必须匹配字段 对象的名称。
  2. 构造函数可以接受所有字段作为参数。
  3. 用户定义的对象(非标量):

    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
    }
    

    <强>功能

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

    步骤默认:

    @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

答案 1 :(得分:1)

我没有找到关于Cucumber for Java对scalar type的含义的明确定义。

我能找到的最佳提示是在为接受DataTable的新步骤生成的代码段中。生成的评论为:

  

对于自动转换,请将DataTable更改为其中一个   列表&lt; YourType&gt;,列表&lt;列表&lt; E&gt;&gt;,列表&lt; Map&lt; K,V&gt;&gt;或地图&lt; K,V&gt;。   E,K,V必须是标量(String,Integer,Date,enum等)

所以看起来除了&#34; Java标量类型&#34; (byteshortintlongcharboolean或其包装类型Byte,{{ 1}},ShortIntegerLongChar)您还可以使用BooleanString和枚举类型。

实际上,一个简短的测试显示我可以使用任何具有构造函数的类型java.util.Date作为参数。

我自己的价值类的一个小例子(非常人为)。以下代码段的输出为String

List<List<MyValueClass>>

答案 2 :(得分:0)

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

如果数据表仅包含一列,则在调用步骤定义之前,黄瓜将通过使用黄瓜自动将数据表扁平化为列表(使用DataTable.asList(String.class))。

答案 3 :(得分:0)

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

Datatable.feature

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

Pojo.class

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