在Java中为Cucumber步骤内的字段定义数据表单元格中的字符串列表

时间:2018-01-19 19:12:56

标签: datatable cucumber cucumber-java transformer

我想要什么

我正在使用Cucumber的DataTables。

我有以下情况:

进入要素文件:

I set the ingredients necessary for a meal
  | name           | ingredients        |
  | mac and cheese | pasta,cheese       |
  | hamburger      | bread,meat,lettuce | 

在StepDefinition文件中我有

@When("I set the ingredients necessary for a meal")
public void setIngredients(List<Meal> meals){
  //do things with it
}

我有一个班级用餐

public class Meal {
  String name;
  List<String> ingredients;
}

这不起作用。

我所知道的

如果我将我的配料领域设置为一个简单的String Cucumber&#34;神奇地&#34;将名称和成分与类的字段相匹配,并且在步骤定义中,我将获得正确填充的膳食列表。 但目前它并没有自动匹配。

我尝试了什么

我尝试将类定义为:

public class Meal {
  String name;
  String ingredients;
  List<String> ingredientsList;
}
  • 有一个构造函数Meal(String,String)可以将成分解析到成分列表中,但它不起作用。

  • 我尝试定义一个用于解析它的成分的setter,并定义ingredientsList但它也不起作用。

  • 我尝试在步骤定义中使用DataTable但仍无法找到将其转换为我的成分列表的方法。

  • 我尝试使用Transformer,但是,AFAIK,我必须为我想要服务的每顿饭定义一个步骤,我必须在步骤中发送值。

我不想要

除了Meal课程之外,我不想被迫在任何地方解析信息。

我是如何暂时解决的

在更完整的Meal定义中,定义了一个setIngredientsList(),用于将成分解析为列表。

在步骤定义中,我遍历膳食列表并为每个膳食调用setIngredientsList。正如我所说,我不希望在Meal课程之外完成任何这样的处理。

问题

有谁知道我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

我会考虑使用Map<String, String>而不是列表。查看您的示例对我来说就像名称值对。地图可能很适合。

如果您的字段在Meal中是私有的,那么您可能不需要构造函数。但是,我会将它们隐藏为私有变量并添加两个参数构造函数。尽可能少暴露的习惯倾向于支持长期维护。

我写了一段blog post,可能对你有所帮助。

答案 1 :(得分:0)

您可以使用@XStreamConverter注释来注册XStream转换器类。

数据表中的列名和所需POJO中的字段需要与Cucumber相同才能为它们分配值。

通过扩展AbstractSingleValueConverter解析逻辑来创建转换器。

public class IngredientConverter extends AbstractSingleValueConverter {

    @Override
    public boolean canConvert(Class type) {
        return type.equals(ArrayList.class);
    }

    @Override
    public Object fromString(String ingreds) {
        return Arrays.asList(ingreds.split(","));
    }
}

使用@XStreamConverter(IngredientConverter.class)

注释成分字段
public class Meal {

    private String name;

    @XStreamConverter(IngredientConverter.class)
    private List<String> ingredients;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getIngredients() {
        return ingredients;
    }

    public void setIngredients(List<String> ingredients) {
        this.ingredients = ingredients;
    }    
}

如果您使用的是Cucumber2,请查看这两个链接,这些链接允许自定义xstreamconverters的全局注册。这些现在是官方黄瓜释放的一部分。 Link 1 Link 2