首页 > 解决方案 > 将黄瓜数据表转换为自定义对象列表,其中对象具有“集合”类型的字段

问题描述

假设在 Cucumber 场景步骤中有一个步骤使用数据表:

我添加了一个新用户

 | firstName | lastName | workEmail        | workPhone      | userName | assignedRoles       | assignedAdvisorCodes |
    | Steven    | Gerrard  | steeveg@test.com | 12312312346345 | steeveg  | Advisor,Compliance  | 1107,1108            |

然后步骤定义看起来像

@And("^我添加了一个新用户$")

public void i_add_a_new_user(List<User> users) {

要点是 'User' POJO 包含 Collection 类型的字段:

public class User {
    private Set<String> assignedRoles;
    private Set<String> assignedAdvisorCodes;

我希望这些字段将填充我在以逗号分隔的黄瓜数据表中指定的内容。

==================

所以,我的问题是 List 中的“用户”对象将被分配数据表中的所有字段,但 assignedRoles 和 assignedAdvisorCodes 除外,因为它们都是 Set 类型(实际上没关系,它可能是 Collection 类型的任何东西)。

请建议如何克服这一点。我使用黄瓜 2.4.0,但即使对于版本 3+,也没有找到任何解决方案。很清楚如何处理具有原始或类数据类型的字段的对象,但不处理 Collection 类型的字段。

标签: javacucumberbdd

解决方案


Cucumber 2.4.0 版中,可以使用 XStream 自定义转换。

public class SetStringConverter implements Converter{

    @Override
    public boolean canConvert(Class arg0) {
        return Set.class.isAssignableFrom(arg0);
    }

    @Override
    public void marshal(Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2) {

    }

    @Override
    public Object unmarshal(HierarchicalStreamReader arg0, UnmarshallingContext arg1) {
        return  new HashSet<String>(Arrays.asList(arg0.getValue().split(",")));
    }
}

有两种方法可以声明它以供 XStream 使用。首先,可以在 POJO 中声明它。这是更好的使用方法。

@XStreamConverter(value = SetStringConverter.class)
private Set<String> assignedRoles;
@XStreamConverter(value = SetStringConverter.class)
private Set<String> assignedAdvisorCodes;

其他人可以在跑步者上全局声明它们。那么就不需要在POJO上声明了。

@XStreamConverters({
    @XStreamConverter(value = SetStringConverter.class)
})
public class RunCucumberTest {
}

Cucumber 版本 3 及更高版本中,XStream 消失了。下面的类在项目中是唯一的,需要在声明的粘合路径中可用。

public class Configurer implements TypeRegistryConfigurer {

    @Override
    public void configureTypeRegistry(TypeRegistry registry) {

        registry.defineDataTableType(new DataTableType(User.class, new TableEntryTransformer<User>() {
            @Override
            public User transform(Map<String, String> entry) {
                return User.createUser(entry);
            }
        }));
    }

    @Override
    public Locale locale() {
        return Locale.ENGLISH;
    }
}

在用户 POJO 中,您需要添加 createUser 方法。

public static User createUser(Map<String, String> entry) {
        User user = new User();
        user.firstName = entry.get("firstName");
        user.lastName = entry.get("lastName");
        user.assignedRoles = new HashSet<String>(Arrays.asList(entry.get("assignedRoles").split(",")));
        user.assignedAdvisorCodes = new HashSet<String>(Arrays.asList(entry.get("assignedAdvisorCodes").split(",")));
        return user;
    }

推荐阅读